aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml26
-rw-r--r--.pre-commit-config.yaml16
-rw-r--r--.travis.yml163
-rw-r--r--INFO32
-rw-r--r--INFO.yaml27
-rw-r--r--PI.md32
-rw-r--r--README.md211
-rw-r--r--ansible/host_vars/127.0.0.15
-rw-r--r--ansible/site.cntt.yml48
-rw-r--r--ansible/site.gate.yml90
-rw-r--r--ansible/site.yml58
-rw-r--r--api/apidoc/functest.ci.check_deployment.rst7
-rw-r--r--api/apidoc/functest.ci.rst17
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.rst2
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.snaps.api_check.rst7
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.snaps.health_check.rst7
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.snaps.rst22
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.snaps.smoke.rst7
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_suite_builder.rst7
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_test_runner.rst7
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_utils.rst7
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.tempest.conf_utils.rst7
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.tempest.rst1
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.vgpu.rst17
-rw-r--r--api/apidoc/functest.opnfv_tests.openstack.vgpu.vgpu.rst7
-rw-r--r--api/apidoc/functest.rst1
-rw-r--r--build.sh57
-rw-r--r--ci/daily.yaml62
-rw-r--r--ci/gate.yaml111
-rw-r--r--ci/globals.yaml13
-rw-r--r--ci/run.yaml217
-rw-r--r--commons/traffic-profile-guidelines.rst8
-rw-r--r--docker/benchmarking-cntt/Dockerfile5
-rw-r--r--docker/benchmarking-cntt/blacklist.yaml48
-rw-r--r--docker/benchmarking-cntt/testcases.yaml67
-rw-r--r--docker/benchmarking/Dockerfile32
-rw-r--r--docker/benchmarking/hooks/post_checkout2
-rw-r--r--docker/benchmarking/testcases.yaml36
-rw-r--r--docker/components/Dockerfile4
-rw-r--r--docker/components/hooks/post_checkout6
-rw-r--r--docker/components/testcases.yaml52
-rw-r--r--docker/core/Dockerfile61
-rw-r--r--docker/core/Switch-to-threading.Thread-for-Rally-tasks.patch49
-rw-r--r--docker/features/Dockerfile30
-rw-r--r--docker/features/hooks/post_checkout6
-rw-r--r--docker/features/testcases.yaml109
-rw-r--r--docker/features/thirdparty-requirements.txt8
-rw-r--r--docker/healthcheck/Dockerfile21
-rw-r--r--docker/healthcheck/testcases.yaml41
-rw-r--r--docker/healthcheck/thirdparty-requirements.txt2
-rw-r--r--docker/smoke-cntt/Dockerfile5
-rw-r--r--docker/smoke-cntt/tempest_conf.yaml104
-rw-r--r--docker/smoke-cntt/testcases.yaml321
-rw-r--r--docker/smoke/Dockerfile114
-rw-r--r--docker/smoke/compute.txt368
-rw-r--r--docker/smoke/hooks/post_checkout2
-rw-r--r--docker/smoke/object.txt66
-rw-r--r--docker/smoke/platform.txt432
-rw-r--r--docker/smoke/testcases.yaml347
-rw-r--r--docker/tempest/Dockerfile40
-rw-r--r--docker/tempest/hooks/post_checkout6
-rw-r--r--docker/vnf/Dockerfile56
-rw-r--r--docker/vnf/clearwater-heat-singlenet-deps.patch1849
-rw-r--r--docker/vnf/hooks/post_checkout2
-rw-r--r--docker/vnf/testcases.yaml11
-rw-r--r--docs/com/css/theme/OPNFV-Berlin.css6
-rw-r--r--docs/com/css/theme/OPNFV.css6
-rw-r--r--docs/com/pres/Summit/Berlin-2016/conversation.html2
-rw-r--r--docs/com/pres/Summit/Berlin-2016/summit-Berlin.html24
-rw-r--r--docs/com/pres/Summit/Berlin-2016/testapi.html16
-rw-r--r--docs/com/pres/compliance/compliance.md97
-rw-r--r--docs/com/pres/compliance/index.html52
-rw-r--r--docs/com/pres/dockerslicing/dockerslicing.md2
-rw-r--r--docs/com/pres/euphrates_functest_evolution/euphrates.md2
-rw-r--r--docs/com/pres/functest2019/functest2019.md105
-rw-r--r--docs/com/pres/functest2019/index.html52
-rw-r--r--docs/com/pres/functest2020/functest2020.md61
-rw-r--r--docs/com/pres/functest2020/index.html52
-rw-r--r--docs/com/pres/gambia/gambia.md178
-rw-r--r--docs/com/pres/gambia/index.html52
-rw-r--r--docs/com/pres/gambia/raspberrypi.jpgbin0 -> 4385395 bytes
-rw-r--r--docs/com/pres/oran/ftth.pngbin0 -> 162001 bytes
-rw-r--r--docs/com/pres/oran/oran.md90
-rw-r--r--docs/com/pres/oran/rc1.pngbin0 -> 360960 bytes
m---------docs/com/pres/reveal.js0
-rw-r--r--docs/com/pres/rfp/index.html52
-rw-r--r--docs/com/pres/rfp/rfp.md97
-rw-r--r--docs/com/pres/stockholm/chainedci.pngbin0 -> 95192 bytes
-rw-r--r--docs/com/pres/stockholm/ftth.pngbin0 -> 162001 bytes
-rw-r--r--docs/com/pres/stockholm/index.html52
-rw-r--r--docs/com/pres/stockholm/stockholm.md164
-rw-r--r--docs/com/pres/vevent202004/index.html52
-rw-r--r--docs/com/pres/vevent202004/vevent202004.md99
-rw-r--r--docs/com/pres/vevent202010/index.html52
-rw-r--r--docs/com/pres/vevent202010/vevent202010.md62
-rw-r--r--docs/conf.py2
-rw-r--r--docs/lfreleng/_static/favicon.ico0
-rw-r--r--docs/lfreleng/_static/logo.pngbin58389 -> 0 bytes
-rw-r--r--docs/lfreleng/conf.py6
-rw-r--r--docs/lfreleng/conf.yaml3
-rw-r--r--docs/release/release-notes/functest-release.rst120
-rw-r--r--docs/release/release-notes/index.rst2
-rw-r--r--docs/results/euphrates/5.0/apex.html398
-rw-r--r--docs/results/euphrates/5.0/compass.html248
-rw-r--r--docs/results/euphrates/5.0/daisy.html42
-rw-r--r--docs/results/euphrates/5.0/fuel@aarch64.html62
-rw-r--r--docs/results/euphrates/5.0/fuel@x86.html124
-rw-r--r--docs/results/euphrates/5.0/joid.html124
-rw-r--r--docs/results/js/default.css2
-rw-r--r--docs/results/js/trend.js4
-rw-r--r--docs/spelling_wordlist.txt151
-rw-r--r--docs/testing/developer/devguide/index.rst69
-rw-r--r--docs/testing/user/configguide/ci.rst16
-rw-r--r--docs/testing/user/configguide/configguide.rst280
-rw-r--r--docs/testing/user/configguide/index.rst14
-rw-r--r--docs/testing/user/configguide/intro.rst3
-rw-r--r--docs/testing/user/configguide/prerequisites.rst13
-rw-r--r--docs/testing/user/userguide/index.rst25
-rw-r--r--docs/testing/user/userguide/reporting.rst4
-rw-r--r--docs/testing/user/userguide/runfunctest.rst114
-rw-r--r--docs/testing/user/userguide/test_details.rst93
-rw-r--r--docs/testing/user/userguide/test_overview.rst79
-rw-r--r--docs/testing/user/userguide/test_results.rst213
-rw-r--r--docs/testing/user/userguide/troubleshooting.rst66
-rw-r--r--elements/functest/element-deps1
-rwxr-xr-xelements/functest/install.d/16-functest14
-rw-r--r--functest/ci/__init__.py0
-rw-r--r--functest/ci/add_proxy.sh127
-rw-r--r--functest/ci/check_deployment.py188
-rw-r--r--functest/ci/config_aarch64_patch.yaml172
-rw-r--r--functest/ci/config_functest.yaml66
-rw-r--r--functest/ci/config_patch.yaml449
-rw-r--r--functest/ci/convert_images.sh8
-rw-r--r--functest/ci/download_images.sh22
-rw-r--r--functest/ci/logging.debug.ini110
-rw-r--r--functest/ci/logging.ini30
-rw-r--r--functest/ci/rally_aarch64_patch.conf2
-rw-r--r--functest/ci/testcases.yaml833
-rw-r--r--functest/core/cloudify.py164
-rw-r--r--functest/core/singlevm.py170
-rw-r--r--functest/core/tenantnetwork.py93
-rw-r--r--functest/opnfv_tests/openstack/api/connection_check.py33
-rw-r--r--functest/opnfv_tests/openstack/barbican/barbican.py8
-rw-r--r--functest/opnfv_tests/openstack/cinder/cinder_test.py26
-rw-r--r--functest/opnfv_tests/openstack/cinder/write_data.sh2
-rw-r--r--functest/opnfv_tests/openstack/patrole/patrole.py22
-rw-r--r--functest/opnfv_tests/openstack/rally/blacklist.txt24
-rw-r--r--functest/opnfv_tests/openstack/rally/blacklist.yaml40
-rw-r--r--functest/opnfv_tests/openstack/rally/macro/macro.yaml6
-rw-r--r--functest/opnfv_tests/openstack/rally/rally.py532
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/full/opnfv-cinder.yaml71
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/full/opnfv-glance.yaml5
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/full/opnfv-neutron.yaml22
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml56
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/opnfv-barbican.yaml98
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/opnfv-quotas.yaml15
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/opnfv-swift.yaml71
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/opnfv-vm.yaml19
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-cinder.yaml20
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-glance.yaml5
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-neutron.yaml12
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-nova.yaml35
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template2
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template2
-rw-r--r--functest/opnfv_tests/openstack/rally/task.yaml14
-rw-r--r--functest/opnfv_tests/openstack/refstack/refstack.py34
-rw-r--r--functest/opnfv_tests/openstack/shaker/shaker.py70
-rw-r--r--functest/opnfv_tests/openstack/snaps/__init__.py0
-rw-r--r--functest/opnfv_tests/openstack/snaps/api_check.py50
-rw-r--r--functest/opnfv_tests/openstack/snaps/health_check.py49
-rw-r--r--functest/opnfv_tests/openstack/snaps/smoke.py48
-rw-r--r--functest/opnfv_tests/openstack/snaps/snaps_suite_builder.py441
-rw-r--r--functest/opnfv_tests/openstack/snaps/snaps_test_runner.py113
-rw-r--r--functest/opnfv_tests/openstack/snaps/snaps_utils.py66
-rw-r--r--functest/opnfv_tests/openstack/tempest/conf_utils.py271
-rw-r--r--functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt2
-rw-r--r--functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml19
-rw-r--r--functest/opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml15
-rw-r--r--functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml117
-rw-r--r--functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf_ovn.yaml104
-rw-r--r--functest/opnfv_tests/openstack/tempest/tempest.py607
-rw-r--r--functest/opnfv_tests/openstack/vgpu/__init__.py0
-rw-r--r--functest/opnfv_tests/openstack/vgpu/vgpu.py54
-rw-r--r--functest/opnfv_tests/openstack/vmtp/vmtp.py75
-rw-r--r--functest/opnfv_tests/openstack/vping/vping_ssh.py21
-rw-r--r--functest/opnfv_tests/openstack/vping/vping_userdata.py26
-rw-r--r--functest/opnfv_tests/sdn/odl/odl.py19
-rw-r--r--functest/opnfv_tests/vnf/epc/juju_epc.py444
-rw-r--r--functest/opnfv_tests/vnf/ims/clearwater.py91
-rw-r--r--functest/opnfv_tests/vnf/ims/cloudify_ims.py225
-rw-r--r--functest/opnfv_tests/vnf/ims/heat_ims.py139
-rw-r--r--functest/opnfv_tests/vnf/ims/heat_ims.yaml4
-rw-r--r--functest/opnfv_tests/vnf/router/cloudify_vrouter.py141
-rw-r--r--functest/opnfv_tests/vnf/router/test_controller/function_test_exec.py17
-rw-r--r--functest/opnfv_tests/vnf/router/utilvnf.py41
-rw-r--r--functest/opnfv_tests/vnf/router/vnf_controller/checker.py2
-rw-r--r--functest/opnfv_tests/vnf/router/vnf_controller/command_generator.py2
-rw-r--r--functest/opnfv_tests/vnf/router/vnf_controller/ssh_client.py8
-rw-r--r--functest/opnfv_tests/vnf/router/vnf_controller/vm_controller.py10
-rw-r--r--functest/opnfv_tests/vnf/router/vnf_controller/vnf_controller.py24
-rw-r--r--functest/opnfv_tests/vnf/router/vrouter_base.py10
-rw-r--r--functest/tests/unit/ci/__init__.py0
-rw-r--r--functest/tests/unit/ci/test_check_deployment.py286
-rw-r--r--functest/tests/unit/odl/test_odl.py51
-rw-r--r--functest/tests/unit/openstack/cinder/test_cinder.py11
-rw-r--r--functest/tests/unit/openstack/rally/test_rally.py164
-rw-r--r--functest/tests/unit/openstack/snaps/__init__.py0
-rw-r--r--functest/tests/unit/openstack/snaps/test_snaps.py251
-rw-r--r--functest/tests/unit/openstack/tempest/test_conf_utils.py164
-rw-r--r--functest/tests/unit/openstack/tempest/test_tempest.py215
-rw-r--r--functest/tests/unit/openstack/vmtp/test_vmtp.py11
-rw-r--r--functest/tests/unit/openstack/vping/test_vping_ssh.py32
-rw-r--r--functest/tests/unit/utils/test_functest_utils.py173
-rw-r--r--functest/tests/unit/vnf/epc/test_juju_epc.py1
-rw-r--r--functest/tests/unit/vnf/ims/test_clearwater.py4
-rw-r--r--functest/utils/config.py16
-rw-r--r--functest/utils/env.py12
-rw-r--r--functest/utils/functest_utils.py107
-rw-r--r--requirements.txt13
-rw-r--r--rtd-requirements.txt3
-rw-r--r--setup.cfg10
-rw-r--r--setup.py8
-rw-r--r--test-requirements.txt16
-rw-r--r--tox.ini118
-rw-r--r--upper-constraints.txt41
225 files changed, 11329 insertions, 6631 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 000000000..f7817da9c
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,26 @@
+---
+version: 2
+jobs:
+ build:
+ docker:
+ - image: circleci/python:3.9
+ steps:
+ - checkout
+ - run:
+ name: Install dependendencies
+ command: sudo apt-get update && sudo apt-get install enchant-2
+ - run:
+ name: Run tox
+ command: sudo pip install tox tox-pip-version && tox
+ - store_artifacts:
+ path: api/build
+ destination: api
+ - store_artifacts:
+ path: docs/build
+ destination: docs
+ - store_artifacts:
+ path: cover
+ destination: cover
+ - store_artifacts:
+ path: coverage.xml
+ destination: coverage.xml
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 000000000..323386c88
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,16 @@
+---
+repos:
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v4.4.0
+ hooks:
+ - id: trailing-whitespace
+ exclude: '.patch$'
+ # trailing blanks shall not preferably be fixed in patch files
+
+ - repo: https://github.com/Lucas-C/pre-commit-hooks
+ rev: v1.4.2
+ hooks:
+ - id: remove-tabs
+ stages: [commit]
+ exclude: '^(.git/|docs/make.bat|docs/Makefile|)'
+
diff --git a/.travis.yml b/.travis.yml
index e4060757f..6b6e0a672 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,96 +2,187 @@
sudo: required
services: docker
language: generic
+dist: focal
before_script:
- - sudo apt-get -y install qemu-user-static
- - sudo pip install tox
+ - sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
+ - sudo pip install tox tox-pip-version
+ - sudo apt-get update && sudo apt-get install -y enchant
- sudo -E docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}"
- (cd .. && git clone https://github.com/estesp/manifest-tool)
+ - (cd ../manifest-tool && git checkout v0.9.0)
- (cd ../manifest-tool && sudo -E make && sudo -E make install)
jobs:
include:
- stage: run unit tests
- script: tox -e docs,pep8,pylint,yamllint,bashate,py27,cover
+ script: >
+ tox -e \
+ docs,pep8,pylint,yamllint,bashate,bandit,py38,cover
- stage: build functest-core images
- script: sudo -E bash build.sh
+ script: sudo -E sh build.sh
env:
- REPO="${DOCKER_USERNAME}"
- amd64_dirs="docker/core"
- arm64_dirs=""
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs=""
+ - arm64_dirs="docker/core"
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs=""
+ - arm64_dirs=""
+ - arm_dirs="docker/core"
- stage: publish functest-core manifests
script: >
sudo manifest-tool push from-args \
- --platforms linux/amd64 \
+ --platforms linux/amd64,linux/arm,linux/arm64 \
--template ${DOCKER_USERNAME}/functest-core:ARCH-latest \
--target ${DOCKER_USERNAME}/functest-core:latest
- - stage: build functest-tempest images
- script: sudo -E bash build.sh
+ - stage: build all functest images
+ script: sudo -E sh build.sh
env:
- REPO="${DOCKER_USERNAME}"
- - amd64_dirs="docker/tempest"
+ - amd64_dirs="docker/healthcheck"
- arm64_dirs=""
- - stage: publish functest-tempest manifests
- script: >
- sudo manifest-tool push from-args \
- --platforms linux/amd64 \
- --template ${DOCKER_USERNAME}/functest-tempest:ARCH-latest \
- --target ${DOCKER_USERNAME}/functest-tempest:latest
- - stage: build all functest images
- script: sudo -E bash build.sh
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
env:
- REPO="${DOCKER_USERNAME}"
- - amd64_dirs="docker/healthcheck"
+ - amd64_dirs=""
+ - arm64_dirs="docker/healthcheck"
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs=""
- arm64_dirs=""
- - script: sudo -E bash build.sh
+ - arm_dirs="docker/healthcheck"
+ - script: sudo -E sh build.sh
env:
- REPO="${DOCKER_USERNAME}"
- amd64_dirs="docker/smoke"
- arm64_dirs=""
- - script: sudo -E bash build.sh
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
env:
- REPO="${DOCKER_USERNAME}"
- - amd64_dirs="docker/benchmarking"
+ - amd64_dirs=""
+ - arm64_dirs="docker/smoke"
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs=""
- arm64_dirs=""
- - script: sudo -E bash build.sh
+ - arm_dirs="docker/smoke"
+ - script: sudo -E sh build.sh
env:
- REPO="${DOCKER_USERNAME}"
- - amd64_dirs="docker/features"
+ - amd64_dirs="docker/benchmarking"
- arm64_dirs=""
- - script: sudo -E bash build.sh
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
env:
- REPO="${DOCKER_USERNAME}"
- - amd64_dirs="docker/components"
+ - amd64_dirs=""
+ - arm64_dirs="docker/benchmarking"
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs=""
- arm64_dirs=""
- - script: sudo -E bash build.sh
+ - arm_dirs="docker/benchmarking"
+ - script: sudo -E sh build.sh
env:
- REPO="${DOCKER_USERNAME}"
- amd64_dirs="docker/vnf"
- arm64_dirs=""
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs=""
+ - arm64_dirs="docker/vnf"
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs=""
+ - arm64_dirs=""
+ - arm_dirs="docker/vnf"
- stage: publish all manifests
script: >
sudo manifest-tool push from-args \
- --platforms linux/amd64 \
+ --platforms linux/amd64,linux/arm,linux/arm64 \
--template ${DOCKER_USERNAME}/functest-healthcheck:ARCH-latest \
--target ${DOCKER_USERNAME}/functest-healthcheck:latest
- script: >
sudo manifest-tool push from-args \
- --platforms linux/amd64 \
+ --platforms linux/amd64,linux/arm,linux/arm64 \
--template ${DOCKER_USERNAME}/functest-smoke:ARCH-latest \
--target ${DOCKER_USERNAME}/functest-smoke:latest
- script: >
sudo manifest-tool push from-args \
- --platforms linux/amd64 \
- --template ${DOCKER_USERNAME}/functest-features:ARCH-latest \
- --target ${DOCKER_USERNAME}/functest-features:latest
- - script: >
- sudo manifest-tool push from-args \
- --platforms linux/amd64 \
- --template ${DOCKER_USERNAME}/functest-components:ARCH-latest \
- --target ${DOCKER_USERNAME}/functest-components:latest
+ --platforms linux/amd64,linux/arm,linux/arm64 \
+ --template ${DOCKER_USERNAME}/functest-benchmarking:ARCH-latest \
+ --target ${DOCKER_USERNAME}/functest-benchmarking:latest
- script: >
sudo manifest-tool push from-args \
- --platforms linux/amd64 \
+ --platforms linux/amd64,linux/arm,linux/arm64 \
--template ${DOCKER_USERNAME}/functest-vnf:ARCH-latest \
--target ${DOCKER_USERNAME}/functest-vnf:latest
+ - stage: build all functest cntt images
+ script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs="docker/smoke-cntt"
+ - arm64_dirs=""
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs=""
+ - arm64_dirs="docker/smoke-cntt"
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs=""
+ - arm64_dirs=""
+ - arm_dirs="docker/smoke-cntt"
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs="docker/benchmarking-cntt"
+ - arm64_dirs=""
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs=""
+ - arm64_dirs="docker/benchmarking-cntt"
+ - arm_dirs=""
+ - script: sudo -E sh build.sh
+ env:
+ - REPO="${DOCKER_USERNAME}"
+ - amd64_dirs=""
+ - arm64_dirs=""
+ - arm_dirs="docker/benchmarking-cntt"
+ - stage: publish all cntt manifests
+ script: >
+ sudo manifest-tool push from-args \
+ --platforms linux/amd64,linux/arm,linux/arm64 \
+ --template ${DOCKER_USERNAME}/functest-smoke-cntt:ARCH-latest \
+ --target ${DOCKER_USERNAME}/functest-smoke-cntt:latest
+ - script: >
+ sudo manifest-tool push from-args \
+ --platforms linux/amd64,linux/arm,linux/arm64 \
+ --template ${DOCKER_USERNAME}/functest-benchmarking-cntt:ARCH-latest \
+ --target ${DOCKER_USERNAME}/functest-benchmarking-cntt:latest
diff --git a/INFO b/INFO
index 0cbec6b4d..eca7c5141 100644
--- a/INFO
+++ b/INFO
@@ -1,9 +1,9 @@
Project: Base System Functionality Testing Project (functest)
Project Creation Date: January 20, 2015
Project Category: Integration & Testing
-Lifecycle State: Incubation
-Primary Contact: Cedric Ollivier (cedric.ollivier@orange.com)
-Project Lead: Cedric Ollivier (cedric.ollivier@orange.com)
+Lifecycle State: Mature
+Primary Contact: Cédric Ollivier (cedric.ollivier@orange.com)
+Project Lead: Cédric Ollivier (cedric.ollivier@orange.com)
Jira Project Name: Base System Functionality Testing Project
Jira Project Prefix: FUNCTEST
Mailing list tag: [functest]
@@ -11,30 +11,6 @@ IRC: Server:freenode.net Channel:#opnfv-functest
Repository: functest
Committers:
-Morgan Richomme <morgan.richomme@orange.com>
-Jose Lausuch <jalausuch@suse.com>
-Cedric Ollivier <cedric.ollivier@orange.com>
-Helen Yao <helanyao@gmail.com>
-Serena Feng <feng.xiaowei@zte.com.cn>
-Juha Kosonen <juha.kosonen@nokia.com>
-Valentin Boucher <valentin.boucher@kontron.com>
-Viktor Tikkanen <viktor.tikkanen@nokia.com>
-Mei Mei <meimei@huawei.com>
-Linda Wang <wangwulin@huawei.com>
-
-Additional contributors:
-Georgios Paraskevopoulos <georgepar.91@gmail.com>
-Romanos Skiadas <rom.skiad@gmail.com>
-Michael Polenchuk <mpolenchuk@mirantis.com>
-Cristina Pauna <cristina.pauna@enea.com>
-Steven Pisarski <s.pisarski@cablelabs.com>
+Cédric Ollivier <cedric.ollivier@orange.com>
Link to TSC approval of the project: http://meetbot.opnfv.org/meetings/opnfv-meeting/2015/opnfv-meeting.2015-01-20-14.57.html
-
-Link(s) to approval of additional committers:
-
-http://lists.opnfv.org/pipermail/opnfv-tech-discuss/2015-April/001971.html
-http://ircbot.wl.linuxfoundation.org/meetings/opnfv-testperf/2015/opnfv-testperf.2015-09-29-13.00.html
-http://ircbot.wl.linuxfoundation.org/meetings/opnfv-testperf/2016/opnfv-testperf.2016-03-01-08.00.html
-http://ircbot.wl.linuxfoundation.org/meetings/opnfv-functest/2016/opnfv-functest.2016-10-11-08.01.html
-
diff --git a/INFO.yaml b/INFO.yaml
index ef0954f18..cf3b176c2 100644
--- a/INFO.yaml
+++ b/INFO.yaml
@@ -2,7 +2,7 @@
project: 'Base System Functionality Testing Project (functest)'
project_creation_date: 'January 20, 2015'
project_category: 'Integration & Testing'
-lifecycle_state: 'Incubation'
+lifecycle_state: 'Mature'
project_lead: &opnfv_functest_ptl
name: 'Cédric Ollivier'
email: 'cedric.ollivier@orange.com'
@@ -37,31 +37,6 @@ repositories:
- 'functest-xtesting'
committers:
- <<: *opnfv_functest_ptl
- - name: 'Morgan Richomme'
- email: 'morgan.richomme@orange.com'
- company: 'orange'
- id: 'mrichomme'
- timezone: ''
- - name: 'valentin boucher'
- email: 'valentin.boucher@kontron.com'
- company: 'kontron'
- id: 'boucherv'
- timezone: ''
- - name: 'Viktor Tikkanen'
- email: 'viktor.tikkanen@nokia.com'
- company: 'nokia'
- id: 'vitikkan'
- timezone: ''
- - name: 'Juha Kosonen'
- email: 'juha.kosonen@nokia.com'
- company: 'nokia'
- id: 'jukosone'
- timezone: ''
- - name: 'Linda Wang'
- email: 'wangwulin@huawei.com'
- company: 'huawei'
- id: 'wangwulin'
- timezone: ''
tsc:
# yamllint disable rule:line-length
approval: 'http//meetbot.opnfv.org/meetings/opnfv-meeting/2015/opnfv-meeting.2015-01-20-14.57.html'
diff --git a/PI.md b/PI.md
new file mode 100644
index 000000000..cc7c25bc8
--- /dev/null
+++ b/PI.md
@@ -0,0 +1,32 @@
+# Run Functest containers on Raspberry PI
+
+All Functest containers (Hunter and newer) are cross-compiled for arm and arm64
+via [travis-ci](https://travis-ci.org/collivier/functest/branches).
+They are built on top of Alpine armhf to support most of Raspberry PI models.
+
+All Docker manifests are published to run these containers via the same
+commands whatever the architecture.
+
+## Copy the image to the SD card
+
+> https://www.raspberrypi.org/documentation/installation/installing-images/linux.md
+>
+> This is very important, as you will lose all the data on the hard drive if you provide the wrong device name.
+> Make sure the device name is the name of the whole SD card as described above, not just a partition. For example: sdd, not sdds1 or sddp1; mmcblk0, not mmcblk0p1.
+
+
+## Install Docker
+
+```shell
+wget https://downloads.raspberrypi.org/raspbian/images/raspbian-2018-11-15/2018-11-13-raspbian-stretch.zip
+unzip 2018-11-13-raspbian-stretch.zip
+sudo dd bs=4M if=2018-11-13-raspbian-stretch.img of=/dev/mmcblk0 conv=fsync
+```
+
+## Install Docker
+
+```shell
+curl -sSL https://get.docker.com | sudo sh
+```
+
+## That's all folks
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..c9f1f03d1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,211 @@
+# Functest
+
+Network virtualization has dramatically modified our architectures which asks
+for more automation and powerful testing tools like Functest, a collection of
+state-of-the-art virtual infrastructure test suites, including automatic VNF
+testing (cf.
+[[1]](https://www.linuxfoundation.org/press-release/2019/05/opnfv-hunter-delivers-test-tools-ci-cd-framework-to-enable-common-nfvi-for-verifying-vnfs/)).
+
+In context of OPNFV, Functest verifies any kind of OpenStack and Kubernetes
+deployments including production environments. It conforms to upstream rules
+and integrates smoothly lots of the test cases available in the opensource
+market. It includes about 3000+ functional tests and 3 hours upstream API and
+dataplane benchmarks. It’s completed by Virtual Network Function deployments
+and testing (vIMS, vRouter and vEPC) to ensure that the platforms meet Network
+Functions Virtualization requirements. Raspberry PI is also supported to verify
+datacenters as the lowest cost (50 euros hardware and software included).
+
+| Functest releases | OpenStack releases |
+|-------------------|--------------------|
+| Jerma | Train |
+| Kali | Ussuri |
+| Leguer | Victoria |
+| Wallaby | Wallaby |
+| **Master** | **next Xena** |
+
+## Prepare your environment
+
+cat env
+```
+DEPLOY_SCENARIO=XXX # if not os-nosdn-nofeature-noha scenario
+NAMESERVER=XXX # if not 8.8.8.8
+EXTERNAL_NETWORK=XXX # if not first network with router:external=True
+DASHBOARD_URL=XXX # else tempest_horizon will be skipped
+NEW_USER_ROLE=XXX # if not member
+SDN_CONTROLLER_IP=XXX # if odl scenario
+VOLUME_DEVICE_NAME=XXX # if not vdb
+FLAVOR_EXTRA_SPECS=hw:mem_page_size:large # if fdio scenarios
+```
+
+cat openstack.creds
+```
+export OS_AUTH_URL=XXX
+export OS_USER_DOMAIN_NAME=XXX
+export OS_PROJECT_DOMAIN_NAME=XXX
+export OS_USERNAME=XXX
+export OS_PROJECT_NAME=XXX
+export OS_PASSWORD=XXX
+export OS_IDENTITY_API_VERSION=3
+export OS_REGION_NAME=XXX
+```
+
+mkdir -p images && wget -q -O- https://git.opnfv.org/functest/plain/functest/ci/download_images.sh | sh -s -- images && ls -1 images/*
+```
+images/cirros-0.6.1-aarch64-disk.img
+images/cirros-0.6.1-x86_64-disk.img
+images/cloudify-docker-manager-community-19.01.24.tar
+images/Fedora-Cloud-Base-30-1.2.x86_64.qcow2
+images/shaker-image-1.3.0+stretch.qcow2
+images/ubuntu-14.04-server-cloudimg-amd64-disk1.img
+images/ubuntu-14.04-server-cloudimg-arm64-uefi1.img
+images/ubuntu-16.04-server-cloudimg-amd64-disk1.img
+images/vyos-1.1.8-amd64.qcow2
+```
+
+## Run healthcheck suite
+
+```shell
+sudo docker run --env-file env \
+ -v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
+ -v $(pwd)/images:/home/opnfv/functest/images \
+ opnfv/functest-healthcheck
+```
+
+```
++--------------------------+------------------+---------------------+------------------+----------------+
+| TEST CASE | PROJECT | TIER | DURATION | RESULT |
++--------------------------+------------------+---------------------+------------------+----------------+
+| connection_check | functest | healthcheck | 00:03 | PASS |
+| tenantnetwork1 | functest | healthcheck | 00:05 | PASS |
+| tenantnetwork2 | functest | healthcheck | 00:06 | PASS |
+| vmready1 | functest | healthcheck | 00:06 | PASS |
+| vmready2 | functest | healthcheck | 00:08 | PASS |
+| singlevm1 | functest | healthcheck | 00:32 | PASS |
+| singlevm2 | functest | healthcheck | 00:37 | PASS |
+| vping_ssh | functest | healthcheck | 00:46 | PASS |
+| vping_userdata | functest | healthcheck | 00:39 | PASS |
+| cinder_test | functest | healthcheck | 01:05 | PASS |
+| tempest_smoke | functest | healthcheck | 05:39 | PASS |
+| tempest_horizon | functest | healthcheck | 01:05 | PASS |
+| odl | functest | healthcheck | 00:00 | SKIP |
++--------------------------+------------------+---------------------+------------------+----------------+
+```
+
+## Run smoke suite
+
+```shell
+sudo docker run --env-file env \
+ -v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
+ -v $(pwd)/images:/home/opnfv/functest/images \
+ opnfv/functest-smoke
+```
+
+```
++---------------------------+------------------+---------------+------------------+----------------+
+| TEST CASE | PROJECT | TIER | DURATION | RESULT |
++---------------------------+------------------+---------------+------------------+----------------+
+| tempest_neutron | functest | smoke | 15:30 | PASS |
+| tempest_cinder | functest | smoke | 02:01 | PASS |
+| tempest_keystone | functest | smoke | 01:17 | PASS |
+| tempest_heat | functest | smoke | 22:14 | PASS |
+| tempest_telemetry | functest | smoke | 00:00 | SKIP |
+| rally_sanity | functest | smoke | 17:24 | PASS |
+| refstack_compute | functest | smoke | 07:03 | PASS |
+| refstack_object | functest | smoke | 02:09 | PASS |
+| refstack_platform | functest | smoke | 07:31 | PASS |
+| tempest_full | functest | smoke | 41:52 | PASS |
+| tempest_scenario | functest | smoke | 08:42 | PASS |
+| tempest_slow | functest | smoke | 43:42 | PASS |
+| patrole_admin | functest | smoke | 21:06 | PASS |
+| patrole_member | functest | smoke | 21:23 | PASS |
+| patrole_reader | functest | smoke | 21:56 | PASS |
+| tempest_barbican | functest | smoke | 02:30 | PASS |
+| tempest_octavia | functest | smoke | 00:00 | SKIP |
+| tempest_cyborg | functest | smoke | 00:00 | SKIP |
++---------------------------+------------------+---------------+------------------+----------------+
+```
+
+## Run smoke CNTT suite
+
+```shell
+sudo docker run --env-file env \
+ -v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
+ -v $(pwd)/images:/home/opnfv/functest/images \
+ opnfv/functest-smoke-cntt
+```
+
+```
++-------------------------------+------------------+---------------+------------------+----------------+
+| TEST CASE | PROJECT | TIER | DURATION | RESULT |
++-------------------------------+------------------+---------------+------------------+----------------+
+| tempest_neutron_cntt | functest | smoke | 11:35 | PASS |
+| tempest_cinder_cntt | functest | smoke | 01:58 | PASS |
+| tempest_keystone_cntt | functest | smoke | 01:13 | PASS |
+| tempest_heat_cntt | functest | smoke | 22:32 | PASS |
+| rally_sanity_cntt | functest | smoke | 17:16 | PASS |
+| tempest_full_cntt | functest | smoke | 41:13 | PASS |
+| tempest_scenario_cntt | functest | smoke | 08:57 | PASS |
+| tempest_slow_cntt | functest | smoke | 35:58 | PASS |
++-------------------------------+------------------+---------------+------------------+----------------+
+```
+
+## Run benchmarking suite
+
+```shell
+sudo docker run --env-file env \
+ -v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
+ -v $(pwd)/images:/home/opnfv/functest/images \
+ opnfv/functest-benchmarking
+```
+
+```
++--------------------+------------------+----------------------+------------------+----------------+
+| TEST CASE | PROJECT | TIER | DURATION | RESULT |
++--------------------+------------------+----------------------+------------------+----------------+
+| rally_full | functest | benchmarking | 93:03 | PASS |
+| rally_jobs | functest | benchmarking | 27:05 | PASS |
+| vmtp | functest | benchmarking | 17:56 | PASS |
+| shaker | functest | benchmarking | 24:02 | PASS |
++--------------------+------------------+----------------------+------------------+----------------+
+```
+
+## Run benchmarking CNTT suite
+
+```shell
+sudo docker run --env-file env \
+ -v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
+ -v $(pwd)/images:/home/opnfv/functest/images \
+ opnfv/functest-benchmarking-cntt
+```
+
+```
++-------------------------+------------------+----------------------+------------------+----------------+
+| TEST CASE | PROJECT | TIER | DURATION | RESULT |
++-------------------------+------------------+----------------------+------------------+----------------+
+| rally_full_cntt | functest | benchmarking | 89:52 | PASS |
+| rally_jobs_cntt | functest | benchmarking | 19:39 | PASS |
+| vmtp | functest | benchmarking | 16:59 | PASS |
+| shaker | functest | benchmarking | 23:43 | PASS |
++-------------------------+------------------+----------------------+------------------+----------------+
+```
+
+## Run vnf suite
+
+```shell
+sudo docker run --env-file env \
+ -v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
+ -v $(pwd)/images:/home/opnfv/functest/images \
+ opnfv/functest-vnf
+```
+
+```
++----------------------+------------------+--------------+------------------+----------------+
+| TEST CASE | PROJECT | TIER | DURATION | RESULT |
++----------------------+------------------+--------------+------------------+----------------+
+| cloudify | functest | vnf | 05:08 | PASS |
+| cloudify_ims | functest | vnf | 24:46 | PASS |
+| heat_ims | functest | vnf | 33:12 | PASS |
+| vyos_vrouter | functest | vnf | 15:53 | PASS |
+| juju_epc | functest | vnf | 27:52 | PASS |
++----------------------+------------------+--------------+------------------+----------------+
+```
diff --git a/ansible/host_vars/127.0.0.1 b/ansible/host_vars/127.0.0.1
new file mode 100644
index 000000000..169b56b07
--- /dev/null
+++ b/ansible/host_vars/127.0.0.1
@@ -0,0 +1,5 @@
+docker_args:
+ env: {}
+ volumes:
+ - /home/opnfv/functest/openstack.creds:/home/opnfv/functest/conf/env_file
+ - /home/opnfv/functest/images:/home/opnfv/functest/images
diff --git a/ansible/site.cntt.yml b/ansible/site.cntt.yml
new file mode 100644
index 000000000..900f619f6
--- /dev/null
+++ b/ansible/site.cntt.yml
@@ -0,0 +1,48 @@
+---
+- hosts:
+ - 127.0.0.1
+ roles:
+ - role: collivier.xtesting
+ project: functest
+ suites:
+ - container: functest-healthcheck
+ tests:
+ - connection_check
+ - tenantnetwork1
+ - tenantnetwork2
+ - vmready1
+ - vmready2
+ - singlevm1
+ - singlevm2
+ - vping_ssh
+ - vping_userdata
+ - cinder_test
+ - odl
+ - tempest_smoke
+ - tempest_horizon
+ - container: functest-smoke-cntt
+ timeout: 2h
+ tests:
+ - tempest_neutron_cntt
+ - tempest_cinder_cntt
+ - tempest_keystone_cntt
+ - tempest_heat_cntt
+ - rally_sanity_cntt
+ - tempest_full_cntt
+ - tempest_scenario_cntt
+ - tempest_slow_cntt
+ - container: functest-benchmarking-cntt
+ timeout: 4h
+ tests:
+ - rally_full_cntt
+ - rally_jobs_cntt
+ - vmtp
+ - shaker
+ - container: functest-vnf
+ timeout: 2h
+ tests:
+ - cloudify
+ - cloudify_ims
+ - heat_ims
+ - vyos_vrouter
+ - juju_epc
diff --git a/ansible/site.gate.yml b/ansible/site.gate.yml
new file mode 100644
index 000000000..ed9ce7812
--- /dev/null
+++ b/ansible/site.gate.yml
@@ -0,0 +1,90 @@
+---
+- hosts:
+ - 127.0.0.1
+ roles:
+ - role: collivier.xtesting
+ project: functest
+ use_gerrit: true
+ gerrit_project: functest
+ git_url: https://gerrit.opnfv.org/gerrit/functest
+ docker_tags:
+ - latest:
+ branch: master
+ dependency: '3.16'
+ builds:
+ dependency:
+ repo: _
+ dport:
+ container: alpine
+ steps:
+ - name: build opnfv/functest-core
+ containers:
+ - name: functest-core
+ ref_arg: BRANCH
+ path: docker/core
+ - name: build containers
+ containers:
+ - name: functest-healthcheck
+ ref_arg: BRANCH
+ path: docker/healthcheck
+ - name: functest-smoke
+ ref_arg: BRANCH
+ path: docker/smoke
+ - name: functest-benchmarking
+ ref_arg: BRANCH
+ path: docker/benchmarking
+ - name: functest-vnf
+ ref_arg:
+ path: docker/vnf
+ suites:
+ - container: functest-healthcheck
+ tests:
+ - connection_check
+ - tenantnetwork1
+ - tenantnetwork2
+ - vmready1
+ - vmready2
+ - singlevm1
+ - singlevm2
+ - vping_ssh
+ - vping_userdata
+ - cinder_test
+ - odl
+ - tempest_smoke
+ - tempest_horizon
+ - container: functest-smoke
+ timeout: 2h
+ tests:
+ - tempest_neutron
+ - tempest_cinder
+ - tempest_keystone
+ - tempest_heat
+ - tempest_telemetry
+ - rally_sanity
+ - refstack_compute
+ - refstack_object
+ - refstack_platform
+ - tempest_full
+ - tempest_scenario
+ - tempest_slow
+ - patrole_admin
+ - patrole_member
+ - patrole_reader
+ - tempest_barbican
+ - tempest_octavia
+ - tempest_cyborg
+ - container: functest-benchmarking
+ timeout: 4h
+ tests:
+ - rally_full
+ - rally_jobs
+ - vmtp
+ - shaker
+ - container: functest-vnf
+ timeout: 2h
+ tests:
+ - cloudify
+ - cloudify_ims
+ - heat_ims
+ - vyos_vrouter
+ - juju_epc
diff --git a/ansible/site.yml b/ansible/site.yml
new file mode 100644
index 000000000..60a2b89e8
--- /dev/null
+++ b/ansible/site.yml
@@ -0,0 +1,58 @@
+---
+- hosts:
+ - 127.0.0.1
+ roles:
+ - role: collivier.xtesting
+ project: functest
+ suites:
+ - container: functest-healthcheck
+ tests:
+ - connection_check
+ - tenantnetwork1
+ - tenantnetwork2
+ - vmready1
+ - vmready2
+ - singlevm1
+ - singlevm2
+ - vping_ssh
+ - vping_userdata
+ - cinder_test
+ - odl
+ - tempest_smoke
+ - tempest_horizon
+ - container: functest-smoke
+ timeout: 2h
+ tests:
+ - tempest_neutron
+ - tempest_cinder
+ - tempest_keystone
+ - tempest_heat
+ - tempest_telemetry
+ - rally_sanity
+ - refstack_compute
+ - refstack_object
+ - refstack_platform
+ - tempest_full
+ - tempest_scenario
+ - tempest_slow
+ - patrole_admin
+ - patrole_member
+ - patrole_reader
+ - tempest_barbican
+ - tempest_octavia
+ - tempest_cyborg
+ - container: functest-benchmarking
+ timeout: 4h
+ tests:
+ - rally_full
+ - rally_jobs
+ - vmtp
+ - shaker
+ - container: functest-vnf
+ timeout: 2h
+ tests:
+ - cloudify
+ - cloudify_ims
+ - heat_ims
+ - vyos_vrouter
+ - juju_epc
diff --git a/api/apidoc/functest.ci.check_deployment.rst b/api/apidoc/functest.ci.check_deployment.rst
deleted file mode 100644
index 278fa3a9a..000000000
--- a/api/apidoc/functest.ci.check_deployment.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-functest.ci.check\_deployment module
-====================================
-
-.. automodule:: functest.ci.check_deployment
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.ci.rst b/api/apidoc/functest.ci.rst
deleted file mode 100644
index 06d0cd508..000000000
--- a/api/apidoc/functest.ci.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-functest.ci package
-===================
-
-Submodules
-----------
-
-.. toctree::
-
- functest.ci.check_deployment
-
-Module contents
----------------
-
-.. automodule:: functest.ci
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.opnfv_tests.openstack.rst b/api/apidoc/functest.opnfv_tests.openstack.rst
index f883cbad4..2a59e8818 100644
--- a/api/apidoc/functest.opnfv_tests.openstack.rst
+++ b/api/apidoc/functest.opnfv_tests.openstack.rst
@@ -12,9 +12,7 @@ Subpackages
functest.opnfv_tests.openstack.rally
functest.opnfv_tests.openstack.refstack
functest.opnfv_tests.openstack.shaker
- functest.opnfv_tests.openstack.snaps
functest.opnfv_tests.openstack.tempest
- functest.opnfv_tests.openstack.vgpu
functest.opnfv_tests.openstack.vmtp
functest.opnfv_tests.openstack.vping
diff --git a/api/apidoc/functest.opnfv_tests.openstack.snaps.api_check.rst b/api/apidoc/functest.opnfv_tests.openstack.snaps.api_check.rst
deleted file mode 100644
index ac540e9c8..000000000
--- a/api/apidoc/functest.opnfv_tests.openstack.snaps.api_check.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-functest.opnfv\_tests.openstack.snaps.api\_check module
-=======================================================
-
-.. automodule:: functest.opnfv_tests.openstack.snaps.api_check
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.opnfv_tests.openstack.snaps.health_check.rst b/api/apidoc/functest.opnfv_tests.openstack.snaps.health_check.rst
deleted file mode 100644
index 81e4fd341..000000000
--- a/api/apidoc/functest.opnfv_tests.openstack.snaps.health_check.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-functest.opnfv\_tests.openstack.snaps.health\_check module
-==========================================================
-
-.. automodule:: functest.opnfv_tests.openstack.snaps.health_check
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.opnfv_tests.openstack.snaps.rst b/api/apidoc/functest.opnfv_tests.openstack.snaps.rst
deleted file mode 100644
index 2bd4ba2c7..000000000
--- a/api/apidoc/functest.opnfv_tests.openstack.snaps.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-functest.opnfv\_tests.openstack.snaps package
-=============================================
-
-Submodules
-----------
-
-.. toctree::
-
- functest.opnfv_tests.openstack.snaps.api_check
- functest.opnfv_tests.openstack.snaps.health_check
- functest.opnfv_tests.openstack.snaps.smoke
- functest.opnfv_tests.openstack.snaps.snaps_suite_builder
- functest.opnfv_tests.openstack.snaps.snaps_test_runner
- functest.opnfv_tests.openstack.snaps.snaps_utils
-
-Module contents
----------------
-
-.. automodule:: functest.opnfv_tests.openstack.snaps
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.opnfv_tests.openstack.snaps.smoke.rst b/api/apidoc/functest.opnfv_tests.openstack.snaps.smoke.rst
deleted file mode 100644
index 90f5a10ad..000000000
--- a/api/apidoc/functest.opnfv_tests.openstack.snaps.smoke.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-functest.opnfv\_tests.openstack.snaps.smoke module
-==================================================
-
-.. automodule:: functest.opnfv_tests.openstack.snaps.smoke
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_suite_builder.rst b/api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_suite_builder.rst
deleted file mode 100644
index e21864f85..000000000
--- a/api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_suite_builder.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-functest.opnfv\_tests.openstack.snaps.snaps\_suite\_builder module
-==================================================================
-
-.. automodule:: functest.opnfv_tests.openstack.snaps.snaps_suite_builder
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_test_runner.rst b/api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_test_runner.rst
deleted file mode 100644
index b72c28ee4..000000000
--- a/api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_test_runner.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-functest.opnfv\_tests.openstack.snaps.snaps\_test\_runner module
-================================================================
-
-.. automodule:: functest.opnfv_tests.openstack.snaps.snaps_test_runner
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_utils.rst b/api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_utils.rst
deleted file mode 100644
index d98919903..000000000
--- a/api/apidoc/functest.opnfv_tests.openstack.snaps.snaps_utils.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-functest.opnfv\_tests.openstack.snaps.snaps\_utils module
-=========================================================
-
-.. automodule:: functest.opnfv_tests.openstack.snaps.snaps_utils
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.opnfv_tests.openstack.tempest.conf_utils.rst b/api/apidoc/functest.opnfv_tests.openstack.tempest.conf_utils.rst
deleted file mode 100644
index 891c7e1f9..000000000
--- a/api/apidoc/functest.opnfv_tests.openstack.tempest.conf_utils.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-functest.opnfv\_tests.openstack.tempest.conf\_utils module
-==========================================================
-
-.. automodule:: functest.opnfv_tests.openstack.tempest.conf_utils
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.opnfv_tests.openstack.tempest.rst b/api/apidoc/functest.opnfv_tests.openstack.tempest.rst
index 40aef5bfc..e1a7a774a 100644
--- a/api/apidoc/functest.opnfv_tests.openstack.tempest.rst
+++ b/api/apidoc/functest.opnfv_tests.openstack.tempest.rst
@@ -6,7 +6,6 @@ Submodules
.. toctree::
- functest.opnfv_tests.openstack.tempest.conf_utils
functest.opnfv_tests.openstack.tempest.tempest
Module contents
diff --git a/api/apidoc/functest.opnfv_tests.openstack.vgpu.rst b/api/apidoc/functest.opnfv_tests.openstack.vgpu.rst
deleted file mode 100644
index 7ba162d24..000000000
--- a/api/apidoc/functest.opnfv_tests.openstack.vgpu.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-functest.opnfv\_tests.openstack.vgpu package
-============================================
-
-Submodules
-----------
-
-.. toctree::
-
- functest.opnfv_tests.openstack.vgpu.vgpu
-
-Module contents
----------------
-
-.. automodule:: functest.opnfv_tests.openstack.vgpu
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.opnfv_tests.openstack.vgpu.vgpu.rst b/api/apidoc/functest.opnfv_tests.openstack.vgpu.vgpu.rst
deleted file mode 100644
index 9bb3b55a5..000000000
--- a/api/apidoc/functest.opnfv_tests.openstack.vgpu.vgpu.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-functest.opnfv\_tests.openstack.vgpu.vgpu module
-================================================
-
-.. automodule:: functest.opnfv_tests.openstack.vgpu.vgpu
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/api/apidoc/functest.rst b/api/apidoc/functest.rst
index b308853d1..e6eb5189c 100644
--- a/api/apidoc/functest.rst
+++ b/api/apidoc/functest.rst
@@ -6,7 +6,6 @@ Subpackages
.. toctree::
- functest.ci
functest.core
functest.opnfv_tests
functest.utils
diff --git a/build.sh b/build.sh
index c6bbd85c3..033d31310 100644
--- a/build.sh
+++ b/build.sh
@@ -1,52 +1,79 @@
-#!/bin/bash
+#!/bin/sh
set -e
repo=${REPO:-opnfv}
amd64_dirs=${amd64_dirs-"\
docker/core \
-docker/tempest \
docker/healthcheck \
docker/smoke \
docker/benchmarking \
-docker/features \
-docker/components \
-docker/vnf"}
+docker/vnf \
+docker/smoke-cntt \
+docker/benchmarking-cntt"}
+arm_dirs=${arm_dirs-${amd64_dirs}}
arm64_dirs=${arm64_dirs-${amd64_dirs}}
-build_opts=(--pull=true --no-cache --force-rm=true)
+build_opts="--pull=true --no-cache --force-rm=true"
find . -name Dockerfile -exec sed -i \
-e "s|opnfv/functest-core|${repo}/functest-core:amd64-latest|g" {} +
find . -name Dockerfile -exec sed -i \
- -e "s|opnfv/functest-tempest|${repo}/functest-tempest:amd64-latest|g" {} +
+ -e "s|opnfv/functest-smoke|${repo}/functest-smoke:amd64-latest|g" {} +
+find . -name Dockerfile -exec sed -i \
+ -e "s|opnfv/functest-benchmarking|\
+${repo}/functest-benchmarking:amd64-latest|g" {} +
for dir in ${amd64_dirs}; do
(cd "${dir}" &&
- docker build "${build_opts[@]}" \
+ docker build $build_opts \
-t "${repo}/functest-${dir##**/}:amd64-latest" .)
docker push "${repo}/functest-${dir##**/}:amd64-latest"
[ "${dir}" != "docker/core" ] &&
(docker rmi "${repo}/functest-${dir##**/}:amd64-latest" || true)
done
-[ ! -z "${amd64_dirs}" ] &&
- (docker rmi "${repo}/functest-core:amd64-latest" alpine:3.8 || true)
+[ -n "${amd64_dirs}" ] &&
+ (docker rmi "${repo}/functest-core:amd64-latest" alpine:3.16 || true)
find . -name Dockerfile -exec git checkout {} +
find . -name Dockerfile -exec sed -i \
- -e "s|alpine:3.8|multiarch/alpine:arm64-v3.8|g" {} +
+ -e "s|alpine:3.16|arm64v8/alpine:3.16|g" {} +
find . -name Dockerfile -exec sed -i \
-e "s|opnfv/functest-core|${repo}/functest-core:arm64-latest|g" {} +
find . -name Dockerfile -exec sed -i \
- -e "s|opnfv/functest-tempest|${repo}/functest-tempest:arm64-latest|g" {} +
+ -e "s|opnfv/functest-smoke|${repo}/functest-smoke:arm64-latest|g" {} +
+find . -name Dockerfile -exec sed -i \
+ -e "s|opnfv/functest-benchmarking|\
+${repo}/functest-benchmarking:arm64-latest|g" {} +
for dir in ${arm64_dirs}; do
- (cd "${dir}" && docker build "${build_opts[@]}" \
+ (cd "${dir}" && docker build $build_opts \
-t "${repo}/functest-${dir##**/}:arm64-latest" .)
docker push "${repo}/functest-${dir##**/}:arm64-latest"
[ "${dir}" != "docker/core" ] &&
(docker rmi "${repo}/functest-${dir##**/}:arm64-latest" || true)
done
-[ ! -z "${arm64_dirs}" ] &&
+[ -n "${arm64_dirs}" ] &&
(docker rmi "${repo}/functest-core:arm64-latest" \
- multiarch/alpine:arm64-v3.8 || true)
+ arm64v8/alpine:3.16 || true)
+find . -name Dockerfile -exec git checkout {} +
+
+find . -name Dockerfile -exec sed -i \
+ -e "s|alpine:3.16|arm32v6/alpine:3.16|g" {} +
+find . -name Dockerfile -exec sed -i \
+ -e "s|opnfv/functest-core|${repo}/functest-core:arm-latest|g" {} +
+find . -name Dockerfile -exec sed -i \
+ -e "s|opnfv/functest-smoke|${repo}/functest-smoke:arm-latest|g" {} +
+find . -name Dockerfile -exec sed -i \
+ -e "s|opnfv/functest-benchmarking|\
+${repo}/functest-benchmarking:arm-latest|g" {} +
+for dir in ${arm_dirs}; do
+ (cd "${dir}" && docker build $build_opts \
+ -t "${repo}/functest-${dir##**/}:arm-latest" .)
+ docker push "${repo}/functest-${dir##**/}:arm-latest"
+ [ "${dir}" != "docker/core" ] &&
+ (docker rmi "${repo}/functest-${dir##**/}:arm-latest" || true)
+done
+[ -n "${arm_dirs}" ] &&
+ (docker rmi "${repo}/functest-core:arm-latest" \
+ arm32v6/alpine:3.16 || true)
find . -name Dockerfile -exec git checkout {} +
exit $?
diff --git a/ci/daily.yaml b/ci/daily.yaml
deleted file mode 100644
index 89b404f77..000000000
--- a/ci/daily.yaml
+++ /dev/null
@@ -1,62 +0,0 @@
----
-- job-template:
- name: '{repo}-functest-{container}-{tag}-pull'
- builders:
- - shell: docker pull {repo}/functest-{container}:{tag}
-
-- project:
- name: '{repo}-functest-{container}-{tag}-pull'
- container:
- - healthcheck
- - smoke
- - benchmarking
- - components
- - vnf
- - features
- jobs:
- - '{repo}-functest-{container}-{tag}-pull'
-
-- job-template:
- name: '{repo}-functest-{tag}-pull'
- project-type: multijob
- builders:
- - multijob:
- name: pull all containers
- projects:
- - name: '{repo}-functest-healthcheck-{tag}-pull'
- - name: '{repo}-functest-smoke-{tag}-pull'
- - name: '{repo}-functest-benchmarking-{tag}-pull'
- - name: '{repo}-functest-components-{tag}-pull'
- - name: '{repo}-functest-vnf-{tag}-pull'
- - name: '{repo}-functest-features-{tag}-pull'
-
-- project:
- name: '{repo}-functest-{tag}-pull'
- jobs:
- - '{repo}-functest-{tag}-pull'
-
-- job-template:
- name: '{repo}-functest-{tag}-daily'
- project-type: multijob
- builders:
- - multijob:
- name: pull containers
- projects:
- - name: '{repo}-functest-{tag}-pull'
- - multijob:
- name: basics tests
- projects:
- - name: '{repo}-functest-healthcheck-{tag}-run'
- - multijob:
- name: advanced tests
- projects:
- - name: '{repo}-functest-smoke-{tag}-run'
- - name: '{repo}-functest-benchmarking-{tag}-run'
- - name: '{repo}-functest-components-{tag}-run'
- - name: '{repo}-functest-vnf-{tag}-run'
- - name: '{repo}-functest-features-{tag}-run'
-
-- project:
- name: '{repo}-functest-{tag}-daily'
- jobs:
- - '{repo}-functest-{tag}-daily'
diff --git a/ci/gate.yaml b/ci/gate.yaml
deleted file mode 100644
index 1abfc67ac..000000000
--- a/ci/gate.yaml
+++ /dev/null
@@ -1,111 +0,0 @@
----
-- functest-buildparameters: &functest-buildparameters
- name: 'functest-buildparameters'
- parameters:
- - string:
- name: branch
- default: '{branch}'
-
-- functest-projectparameters: &functest-projectparameters
- name: 'functest-projectparameters'
- current-parameters: true
-
-- scm:
- name: functest-gerrit
- scm:
- - git:
- url: https://gerrit.opnfv.org/gerrit/functest
- refspec: '+refs/changes/*:refs/changes/*'
- branches:
- - ${branch}
-
-- job-template:
- name: '{repo}-functest-{container}-{tag}-build'
- <<: *functest-buildparameters
- scm:
- - functest-gerrit
- builders:
- - shell: |
- cd docker/$(echo {container} |cut -d\- -f 2)
- docker build \
- --pull=false --no-cache --force-rm=true \
- --build-arg BRANCH=${{branch}} \
- -t {repo}/functest-{container}:{tag} .
-
-- project:
- name: '{repo}-functest-{container}-{tag}-build'
- container:
- - core
- - tempest
- - healthcheck
- - smoke
- - benchmarking
- - components
- - vnf
- - features
- jobs:
- - '{repo}-functest-{container}-{tag}-build'
-
-- job-template:
- name: '{repo}-functest-{tag}-build'
- project-type: multijob
- <<: *functest-buildparameters
- builders:
- - multijob:
- name: build functest-core
- projects:
- - name: '{repo}-functest-core-{tag}-build'
- <<: *functest-projectparameters
- - multijob:
- name: build functest-tempest
- projects:
- - name: '{repo}-functest-tempest-{tag}-build'
- <<: *functest-projectparameters
- - multijob:
- name: build all remaining contrainers
- projects:
- - name: '{repo}-functest-healthcheck-{tag}-build'
- <<: *functest-projectparameters
- - name: '{repo}-functest-smoke-{tag}-build'
- <<: *functest-projectparameters
- - name: '{repo}-functest-benchmarking-{tag}-build'
- <<: *functest-projectparameters
- - name: '{repo}-functest-components-{tag}-build'
- <<: *functest-projectparameters
- - name: '{repo}-functest-vnf-{tag}-build'
- <<: *functest-projectparameters
- - name: '{repo}-functest-features-{tag}-build'
- <<: *functest-projectparameters
-
-- project:
- name: '{repo}-functest-{tag}-build'
- jobs:
- - '{repo}-functest-{tag}-build'
-
-- job-template:
- name: '{repo}-functest-{tag}-gate'
- project-type: multijob
- <<: *functest-buildparameters
- builders:
- - multijob:
- name: build containers
- projects:
- - name: '{repo}-functest-{tag}-build'
- <<: *functest-projectparameters
- - multijob:
- name: basics tests
- projects:
- - name: '{repo}-functest-healthcheck-{tag}-run'
- - multijob:
- name: advanced tests
- projects:
- - name: '{repo}-functest-smoke-{tag}-run'
- - name: '{repo}-functest-benchmarking-{tag}-run'
- - name: '{repo}-functest-components-{tag}-run'
- - name: '{repo}-functest-vnf-{tag}-run'
- - name: '{repo}-functest-features-{tag}-run'
-
-- project:
- name: '{repo}-functest-{tag}-gate'
- jobs:
- - '{repo}-functest-{tag}-gate'
diff --git a/ci/globals.yaml b/ci/globals.yaml
deleted file mode 100644
index 20217921f..000000000
--- a/ci/globals.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
----
-- defaults:
- name: global
- repo: 'opnfv'
- branch: 'master'
- tag: 'latest'
-
-- defaults:
- name: functest-defaults
- prefix: '/home/opnfv/functest'
- nameserver: '8.8.8.8'
- external_network: 'ext-net'
- storage_protocol: 'iSCSI'
diff --git a/ci/run.yaml b/ci/run.yaml
deleted file mode 100644
index c7e27eccc..000000000
--- a/ci/run.yaml
+++ /dev/null
@@ -1,217 +0,0 @@
----
-- job-template:
- name: '{repo}-functest-{container}-{test}-{tag}-run'
- defaults: 'functest-defaults'
- builders:
- - shell: |
- docker run \
- -e NAMESERVER={nameserver} \
- -e EXTERNAL_NETWORK={external_network} \
- -e STORAGE_PROTOCOL={storage_protocol} \
- -v \
- {prefix}/results/$JOB_NAME-$BUILD_ID:/home/opnfv/functest/results \
- -v {prefix}/openstack.creds:/home/opnfv/functest/conf/env_file \
- -v {prefix}/images:/home/opnfv/functest/images \
- {repo}/functest-{container}:{tag} run_tests -t {test}
-
-- project:
- name: '{repo}-functest-healthcheck-{test}-{tag}-run'
- container: healthcheck
- test:
- - connection_check
- - tenantnetwork1
- - tenantnetwork2
- - vmready1
- - vmready2
- - singlevm1
- - singlevm2
- - vping_ssh
- - vping_userdata
- - cinder_test
- - odl
- - api_check
- - snaps_health_check
- jobs:
- - '{repo}-functest-{container}-{test}-{tag}-run'
-
-- job-template:
- name: '{repo}-functest-healthcheck-{tag}-run'
- project-type: multijob
- builders:
- - multijob:
- name: healthcheck
- projects:
- - name: '{repo}-functest-healthcheck-connection_check-{tag}-run'
- - name: '{repo}-functest-healthcheck-tenantnetwork1-{tag}-run'
- - name: '{repo}-functest-healthcheck-tenantnetwork2-{tag}-run'
- - name: '{repo}-functest-healthcheck-vmready1-{tag}-run'
- - name: '{repo}-functest-healthcheck-vmready2-{tag}-run'
- - name: '{repo}-functest-healthcheck-singlevm1-{tag}-run'
- - name: '{repo}-functest-healthcheck-singlevm2-{tag}-run'
- - name: '{repo}-functest-healthcheck-vping_ssh-{tag}-run'
- - name: '{repo}-functest-healthcheck-vping_userdata-{tag}-run'
- - name: '{repo}-functest-healthcheck-cinder_test-{tag}-run'
- - name: '{repo}-functest-healthcheck-odl-{tag}-run'
- - name: '{repo}-functest-healthcheck-api_check-{tag}-run'
- - name: '{repo}-functest-healthcheck-snaps_health_check-{tag}-run'
-
-- project:
- name: '{repo}-functest-healthcheck-{tag}-run'
- jobs:
- - '{repo}-functest-healthcheck-{tag}-run'
-
-- project:
- name: '{repo}-functest-smoke-{test}-{tag}-run'
- container: smoke
- test:
- - tempest_smoke
- - neutron-tempest-plugin-api
- - rally_sanity
- - rally_jobs
- - refstack_defcore
- - patrole
- - snaps_smoke
- - neutron_trunk
- - networking-bgpvpn
- - networking-sfc
- - barbican
- jobs:
- - '{repo}-functest-{container}-{test}-{tag}-run'
-
-- job-template:
- name: '{repo}-functest-smoke-{tag}-run'
- project-type: multijob
- builders:
- - multijob:
- name: smoke
- projects:
- - name: '{repo}-functest-smoke-tempest_smoke-{tag}-run'
- - name: '{repo}-functest-smoke-neutron-tempest-plugin-api-{tag}-run'
- - name: '{repo}-functest-smoke-rally_sanity-{tag}-run'
- - name: '{repo}-functest-smoke-rally_jobs-{tag}-run'
- - name: '{repo}-functest-smoke-refstack_defcore-{tag}-run'
- - name: '{repo}-functest-smoke-patrole-{tag}-run'
- - name: '{repo}-functest-smoke-snaps_smoke-{tag}-run'
- - name: '{repo}-functest-smoke-neutron_trunk-{tag}-run'
- - name: '{repo}-functest-smoke-networking-bgpvpn-{tag}-run'
- - name: '{repo}-functest-smoke-networking-sfc-{tag}-run'
- - name: '{repo}-functest-smoke-barbican-{tag}-run'
-
-- project:
- name: '{repo}-functest-smoke-{tag}-run'
- jobs:
- - '{repo}-functest-smoke-{tag}-run'
-
-- project:
- name: '{repo}-functest-benchmarking-{test}-{tag}-run'
- container: benchmarking
- test:
- - vmtp
- - shaker
- jobs:
- - '{repo}-functest-{container}-{test}-{tag}-run'
-
-- job-template:
- name: '{repo}-functest-benchmarking-{tag}-run'
- project-type: multijob
- builders:
- - multijob:
- name: smoke
- projects:
- - name: '{repo}-functest-benchmarking-vmtp-{tag}-run'
- - name: '{repo}-functest-benchmarking-shaker-{tag}-run'
-
-- project:
- name: '{repo}-functest-benchmarking-{tag}-run'
- jobs:
- - '{repo}-functest-benchmarking-{tag}-run'
-
-- project:
- name: '{repo}-functest-components-{test}-{tag}-run'
- container: components
- test:
- - tempest_full
- - tempest_scenario
- - rally_full
- jobs:
- - '{repo}-functest-{container}-{test}-{tag}-run'
-
-- job-template:
- name: '{repo}-functest-components-{tag}-run'
- project-type: multijob
- builders:
- - multijob:
- name: components
- projects:
- - name: '{repo}-functest-components-tempest_full-{tag}-run'
- - name: '{repo}-functest-components-tempest_scenario-{tag}-run'
- - name: '{repo}-functest-components-rally_full-{tag}-run'
-
-- project:
- name: '{repo}-functest-components-{tag}-run'
- jobs:
- - '{repo}-functest-components-{tag}-run'
-
-- project:
- name: '{repo}-functest-vnf-{test}-{tag}-run'
- container: vnf
- test:
- - cloudify
- - cloudify_ims
- - heat_ims
- - vyos_vrouter
- - juju_epc
- jobs:
- - '{repo}-functest-{container}-{test}-{tag}-run'
-
-- job-template:
- name: '{repo}-functest-vnf-{tag}-run'
- project-type: multijob
- builders:
- - multijob:
- name: vnf
- projects:
- - name: '{repo}-functest-vnf-cloudify-{tag}-run'
- - name: '{repo}-functest-vnf-cloudify_ims-{tag}-run'
- - name: '{repo}-functest-vnf-heat_ims-{tag}-run'
- - name: '{repo}-functest-vnf-vyos_vrouter-{tag}-run'
- - name: '{repo}-functest-vnf-juju_epc-{tag}-run'
-
-- project:
- name: '{repo}-functest-vnf-{tag}-run'
- jobs:
- - '{repo}-functest-vnf-{tag}-run'
-
-- project:
- name: '{repo}-functest-features-{test}-{tag}-run'
- container: features
- test:
- - doctor-notification
- - bgpvpn
- - functest-odl-sfc
- - barometercollectd
- - fds
- - vgpu
- - stor4nfv_os
- jobs:
- - '{repo}-functest-{container}-{test}-{tag}-run'
-
-- job-template:
- name: '{repo}-functest-features-{tag}-run'
- project-type: multijob
- builders:
- - multijob:
- name: features
- projects:
- - name: '{repo}-functest-features-doctor-notification-{tag}-run'
- - name: '{repo}-functest-features-bgpvpn-{tag}-run'
- - name: '{repo}-functest-features-functest-odl-sfc-{tag}-run'
- - name: '{repo}-functest-features-barometercollectd-{tag}-run'
- - name: '{repo}-functest-features-fds-{tag}-run'
- - name: '{repo}-functest-features-vgpu-{tag}-run'
- - name: '{repo}-functest-features-stor4nfv_os-{tag}-run'
-
-- project:
- name: '{repo}-functest-features-{tag}-run'
- jobs:
- - '{repo}-functest-features-{tag}-run'
diff --git a/commons/traffic-profile-guidelines.rst b/commons/traffic-profile-guidelines.rst
index 0b965b156..9619af6eb 100644
--- a/commons/traffic-profile-guidelines.rst
+++ b/commons/traffic-profile-guidelines.rst
@@ -11,11 +11,11 @@ Introduction
------------
In order to have consistent testing profiles, it has been suggested to define and store traffic profiles.
-These profiles shall be based on operator representative scenario.
+These profiles shall be based on operator representative scenario.
-These reference profiles may be used by any test projects, unitary, functional or performance tests.
-It is possible to adapt them to specific testcases.
-It is recommended to use them in order to avoid getting as many profiles as tests.
+These reference profiles may be used by any test projects, unitary, functional or performance tests.
+It is possible to adapt them to specific testcases.
+It is recommended to use them in order to avoid getting as many profiles as tests.
It should be helpful to compare the results of test scenario.
.. _howto:
diff --git a/docker/benchmarking-cntt/Dockerfile b/docker/benchmarking-cntt/Dockerfile
new file mode 100644
index 000000000..46acaa036
--- /dev/null
+++ b/docker/benchmarking-cntt/Dockerfile
@@ -0,0 +1,5 @@
+FROM opnfv/functest-benchmarking
+
+COPY testcases.yaml /etc/xtesting/testcases.yaml
+COPY blacklist.yaml /src/functest/functest/opnfv_tests/openstack/rally/blacklist.yaml
+CMD ["run_tests", "-t", "all"]
diff --git a/docker/benchmarking-cntt/blacklist.yaml b/docker/benchmarking-cntt/blacklist.yaml
new file mode 100644
index 000000000..7ef906df6
--- /dev/null
+++ b/docker/benchmarking-cntt/blacklist.yaml
@@ -0,0 +1,48 @@
+---
+scenario:
+ -
+ scenarios:
+ - '^os-'
+ tests:
+ - 'NeutronNetworks.associate_and_dissociate_floating_ips'
+ - 'NeutronNetworks.create_and_bind_ports'
+ - 'NeutronNetworks.create_and_delete_floating_ips'
+ - 'NeutronNetworks.create_and_list_floating_ips'
+ - 'NeutronSecurityGroup.create_and_delete_security_group_rule'
+ - 'NeutronSecurityGroup.create_and_delete_security_groups'
+ - 'NeutronSecurityGroup.create_and_list_security_group_rules'
+ - 'NeutronSecurityGroup.create_and_list_security_groups'
+ - 'NeutronSecurityGroup.create_and_show_security_group'
+ - 'NeutronSecurityGroup.create_and_show_security_group_rule'
+ - 'NeutronSecurityGroup.create_and_update_security_groups'
+ - 'NovaServers.boot_and_delete_server'
+
+functionality:
+ -
+ functions:
+ - block_migration
+ tests:
+ - NovaServers.boot_server_from_volume_and_live_migrate
+ -
+ functions:
+ - no_migration
+ tests:
+ - NovaServers.boot_and_live_migrate_server
+ - NovaServers.boot_server_attach_created_volume_and_live_migrate
+ - NovaServers.boot_server_from_volume_and_live_migrate
+ - NovaServers.boot_and_migrate_server
+ -
+ functions:
+ - no_net_trunk_service
+ tests:
+ - '^NeutronTrunk'
+ -
+ functions:
+ - no_floating_ip
+ tests:
+ - HeatStacks.create_and_delete_stack
+ - NovaServers.boot_and_associate_floating_ip
+ - NovaServers.boot_server_associate_and_dissociate_floating_ip
+ - NeutronNetworks.create_and_delete_floating_ips
+ - NeutronNetworks.create_and_list_floating_ips
+ - NeutronNetworks.associate_and_dissociate_floating_ips
diff --git a/docker/benchmarking-cntt/testcases.yaml b/docker/benchmarking-cntt/testcases.yaml
new file mode 100644
index 000000000..30eb3e631
--- /dev/null
+++ b/docker/benchmarking-cntt/testcases.yaml
@@ -0,0 +1,67 @@
+---
+tiers:
+ -
+ name: benchmarking_cntt
+ description: >-
+ Run several OpenStack performance tools
+ https://docs.openstack.org/performance-docs/latest/methodologies/tools.html
+ testcases:
+ -
+ case_name: rally_full_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs the full suite of scenarios of the
+ OpenStack Rally suite using several threads and iterations.
+ run:
+ name: rally_full
+ args:
+ tests:
+ - 'authenticate'
+ - 'glance'
+ - 'cinder'
+ - 'heat'
+ - 'keystone'
+ - 'neutron'
+ - 'nova'
+ - 'quotas'
+ - 'swift'
+
+ -
+ case_name: rally_jobs_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs a group of Rally jobs used in
+ OpenStack gating
+ run:
+ name: rally_jobs
+ args:
+ tests:
+ - 'neutron'
+ -
+ case_name: vmtp
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ VMTP is a small python application that will automatically
+ perform ping connectivity, round trip time measurement
+ (latency) and TCP/UDP throughput
+ run:
+ name: vmtp
+
+ -
+ case_name: shaker
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ Shaker wraps around popular system network testing tools
+ like iperf, iperf3 and netperf (with help of flent). Shaker
+ is able to deploy OpenStack instances and networks in
+ different topologies.
+ run:
+ name: shaker
diff --git a/docker/benchmarking/Dockerfile b/docker/benchmarking/Dockerfile
index ff87f56d6..d0957f6b8 100644
--- a/docker/benchmarking/Dockerfile
+++ b/docker/benchmarking/Dockerfile
@@ -1,26 +1,30 @@
FROM opnfv/functest-core
-ARG BRANCH=master
-ARG OPENSTACK_TAG=master
-ARG VMTP_TAG=99b261ccccc2f8a08ee2d8fca9f54ef9d69899d7
+ARG VMTP_TAG=34a82c9f3598ec7f5d8de0a6d5139b92931db4cc
+ARG NEUTRON_TAG=master
RUN apk --no-cache add --update libxml2 libxslt && \
apk --no-cache add --virtual .build-deps --update \
- python-dev build-base linux-headers libffi-dev \
+ python3-dev build-base linux-headers libffi-dev \
openssl-dev libjpeg-turbo-dev libxml2-dev libxslt-dev && \
- wget -q -O- https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=$OPENSTACK_TAG | \
- sed -E s/^tempest==+\(.*\)$/-e\ git+https:\\/\\/git.openstack.org\\/openstack\\/tempest@\\1#egg=tempest/ \
- > upper-constraints.txt && \
- wget -q -O- https://git.opnfv.org/functest/plain/upper-constraints.txt?h=$BRANCH | \
- sed -E /#egg=functest/d > upper-constraints.opnfv.txt && \
+ case $(uname -m) in aarch*|arm*) CFLAGS="-O0" \
+ pip3 install --use-deprecated=legacy-resolver --no-cache-dir -c/src/requirements/upper-constraints.txt \
+ -c/src/functest/upper-constraints.txt lxml ;; esac && \
git init /src/vmtp && \
(cd /src/vmtp && \
- git fetch --tags https://git.openstack.org/openstack/vmtp.git $VMTP_TAG && \
+ git fetch --tags https://review.opendev.org/x/vmtp.git $VMTP_TAG && \
git checkout FETCH_HEAD) && \
- update-requirements -s --source /src/openstack-requirements /src/vmtp/ && \
- pip install --no-cache-dir --src /src -cupper-constraints.txt -cupper-constraints.opnfv.txt \
+ update-requirements -s --source /src/requirements /src/vmtp/ && \
+ pip3 install --use-deprecated=legacy-resolver --no-cache-dir --src /src -c/src/requirements/upper-constraints.txt \
+ -c/src/functest/upper-constraints.txt \
/src/vmtp && \
- rm -r upper-constraints.txt upper-constraints.opnfv.txt src/vmtp && \
+ mkdir -p /home/opnfv/functest/data/rally/neutron/rally-jobs && \
+ git init /src/neutron && \
+ (cd /src/neutron && \
+ git fetch --tags https://opendev.org/openstack/neutron.git $NEUTRON_TAG && \
+ git checkout FETCH_HEAD) && \
+ cp /src/neutron/rally-jobs/task-neutron.yaml /home/opnfv/functest/data/rally/neutron/rally-jobs/ && \
+ rm -r /src/vmtp /src/neutron && \
apk del .build-deps
-COPY testcases.yaml /usr/lib/python2.7/site-packages/xtesting/ci/testcases.yaml
+COPY testcases.yaml /etc/xtesting/testcases.yaml
CMD ["run_tests", "-t", "all"]
diff --git a/docker/benchmarking/hooks/post_checkout b/docker/benchmarking/hooks/post_checkout
index 8d0e98124..c347524ea 100644
--- a/docker/benchmarking/hooks/post_checkout
+++ b/docker/benchmarking/hooks/post_checkout
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
from="${DOCKER_REPO%/*}/functest-core:${DOCKER_TAG}"
sed -i "s|^FROM.*$|FROM ${from}|" Dockerfile
diff --git a/docker/benchmarking/testcases.yaml b/docker/benchmarking/testcases.yaml
index 0c4372679..c84d3a00f 100644
--- a/docker/benchmarking/testcases.yaml
+++ b/docker/benchmarking/testcases.yaml
@@ -2,12 +2,42 @@
tiers:
-
name: benchmarking
- order: 2
description: >-
Run several OpenStack performance tools
https://docs.openstack.org/performance-docs/latest/methodologies/tools.html
testcases:
-
+ case_name: rally_full
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs the full suite of scenarios of the
+ OpenStack Rally suite using several threads and iterations.
+ run:
+ name: rally_full
+ args:
+ optional:
+ - 'gnocchi'
+ - 'barbican'
+
+ -
+ case_name: rally_jobs
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs a group of Rally jobs used in
+ OpenStack gating
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
+ run:
+ name: rally_jobs
+ args:
+ optional:
+ - 'gnocchi'
+
+ -
case_name: vmtp
project_name: functest
criteria: 100
@@ -17,7 +47,7 @@ tiers:
perform ping connectivity, round trip time measurement
(latency) and TCP/UDP throughput
dependencies:
- - POD_ARCH: '^(?!aarch64$)'
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: vmtp
@@ -31,5 +61,7 @@ tiers:
like iperf, iperf3 and netperf (with help of flent). Shaker
is able to deploy OpenStack instances and networks in
different topologies.
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: shaker
diff --git a/docker/components/Dockerfile b/docker/components/Dockerfile
deleted file mode 100644
index 1153e9d1a..000000000
--- a/docker/components/Dockerfile
+++ /dev/null
@@ -1,4 +0,0 @@
-FROM opnfv/functest-tempest
-
-COPY testcases.yaml /usr/lib/python2.7/site-packages/xtesting/ci/testcases.yaml
-CMD ["run_tests", "-t", "all"]
diff --git a/docker/components/hooks/post_checkout b/docker/components/hooks/post_checkout
deleted file mode 100644
index 8d0e98124..000000000
--- a/docker/components/hooks/post_checkout
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-from="${DOCKER_REPO%/*}/functest-core:${DOCKER_TAG}"
-sed -i "s|^FROM.*$|FROM ${from}|" Dockerfile
-
-exit $?
diff --git a/docker/components/testcases.yaml b/docker/components/testcases.yaml
deleted file mode 100644
index 73a88aeb7..000000000
--- a/docker/components/testcases.yaml
+++ /dev/null
@@ -1,52 +0,0 @@
----
-tiers:
- -
- name: components
- order: 4
- description: >-
- Extensive testing of OpenStack API.
- testcases:
- -
- case_name: tempest_full
- project_name: functest
- criteria: 100
- blocking: false
- description: >-
- The list of test cases is generated by
- Tempest automatically and depends on the parameters of
- the OpenStack deployment.
- https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L83
- run:
- name: tempest_common
- args:
- mode: '(?!.*\[.*\bslow\b.*\])(^tempest\.api)'
- option:
- - '--concurrency=4'
-
- -
- case_name: tempest_scenario
- project_name: functest
- criteria: 100
- blocking: false
- description: >-
- The list of test cases is generated by
- Tempest automatically and depends on the parameters of
- the OpenStack deployment.
- https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L84
- run:
- name: tempest_common
- args:
- mode: '(?!.*\[.*\bslow\b.*\])(^tempest\.scenario)'
- option:
- - '--concurrency=1'
-
- -
- case_name: rally_full
- project_name: functest
- criteria: 100
- blocking: false
- description: >-
- This test case runs the full suite of scenarios of the
- OpenStack Rally suite using several threads and iterations.
- run:
- name: rally_full
diff --git a/docker/core/Dockerfile b/docker/core/Dockerfile
index eaedf2a29..2715cce39 100644
--- a/docker/core/Dockerfile
+++ b/docker/core/Dockerfile
@@ -1,34 +1,49 @@
-FROM alpine:3.8
+FROM alpine:3.16
ARG BRANCH=master
ARG OPENSTACK_TAG=master
-ARG PIP_TAG=18.0
-RUN apk --no-cache add --update \
- python libffi libssl1.0 libjpeg-turbo py-pip bash \
- grep sed wget ca-certificates git openssh-client qemu-img && \
+COPY Switch-to-threading.Thread-for-Rally-tasks.patch /tmp/Switch-to-threading.Thread-for-Rally-tasks.patch
+RUN apk -U upgrade && \
+ apk --no-cache add --update \
+ python3 py3-wheel libffi openssl libjpeg-turbo py3-pip bash \
+ grep sed wget ca-certificates git openssh-client qemu-img iputils coreutils mailcap libstdc++ \
+ libxml2 libxslt && \
apk --no-cache add --virtual .build-deps --update \
- python-dev build-base linux-headers libffi-dev \
- openssl-dev libjpeg-turbo-dev && \
- wget -q -O- https://git.opnfv.org/functest/plain/upper-constraints.txt?h=$BRANCH | \
- sed -E /#egg=functest/d > upper-constraints.txt && \
- pip install --no-cache-dir --src /src -cupper-constraints.txt \
- -chttps://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=$OPENSTACK_TAG \
- pip==$PIP_TAG && \
- pip install --no-cache-dir --src /src -cupper-constraints.txt \
- -chttps://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=$OPENSTACK_TAG \
- -e git+https://git.openstack.org/openstack/requirements@$OPENSTACK_TAG#egg=openstack_requirements && \
+ python3-dev build-base linux-headers libffi-dev \
+ openssl-dev libjpeg-turbo-dev rust cargo \
+ libxml2-dev libxslt-dev && \
+ git init /src/requirements && \
+ (cd /src/requirements && \
+ git fetch --tags https://review.opendev.org/openstack/requirements $OPENSTACK_TAG && \
+ git checkout FETCH_HEAD) && \
git init /src/functest && \
(cd /src/functest && \
git fetch --tags https://gerrit.opnfv.org/gerrit/functest $BRANCH && \
git checkout FETCH_HEAD) && \
- update-requirements -s --source /src/openstack-requirements /src/functest && \
- pip install --no-cache-dir --src /src -cupper-constraints.txt \
- -chttps://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=$OPENSTACK_TAG \
- /src/functest && \
- rm -r upper-constraints.txt /src/functest && \
- cp /usr/lib/python2.7/site-packages/functest/ci/logging.ini /usr/lib/python2.7/site-packages/xtesting/ci/ && \
- bash -c "mkdir -p /var/lib/xtesting /home/opnfv" && \
+ sed -i -E /^tempest==+.*$/d /src/requirements/upper-constraints.txt && \
+ sed -i -E /^packaging==+.*$/d /src/requirements/upper-constraints.txt && \
+ case $(uname -m) in aarch*|arm*) sed -i -E /^PyNaCl=/d /src/requirements/upper-constraints.txt && apk add --no-cache py3-pynacl ;; esac && \
+ sed -i -E /#egg=functest/d /src/functest/upper-constraints.txt && \
+ pip3 install --use-deprecated=legacy-resolver --no-cache-dir --src /src -c/src/functest/upper-constraints.txt -c/src/requirements/upper-constraints.txt \
+ -e /src/requirements && \
+ update-requirements -s --source /src/requirements /src/functest && \
+ pip3 install --use-deprecated=legacy-resolver --no-cache-dir --src /src -c/src/functest/upper-constraints.txt -c/src/requirements/upper-constraints.txt \
+ -e /src/functest && \
+ (cd /src/rally && patch -p1 < /tmp/Switch-to-threading.Thread-for-Rally-tasks.patch) && \
+ sed -i -E /#egg=rally/d /src/functest/upper-constraints.txt && \
+ sed -i -E /#egg=tempest/d /src/functest/upper-constraints.txt && \
+ rm -r /src/requirements/.git /src/functest/.git \
+ /tmp/Switch-to-threading.Thread-for-Rally-tasks.patch && \
+ mkdir -p /etc/xtesting && \
+ cp /src/functest/functest/ci/logging.ini /etc/xtesting/ && \
+ cp /src/functest/functest/ci/logging.debug.ini /etc/xtesting/ && \
+ sh -c "mkdir -p /var/lib/xtesting /home/opnfv" && \
ln -s /var/lib/xtesting /home/opnfv/functest && \
- bash -c "mkdir -p /home/opnfv/functest{/conf,/data,/images,/results} /home/opnfv/repos/vnfs" && \
+ sh -c "mkdir -p /home/opnfv/functest/conf /home/opnfv/functest/conf/data /home/opnfv/functest/conf/images /home/opnfv/functest/conf/results && \
+ mkdir -p /home/opnfv/repos/vnfs" && \
+ mkdir -p /etc/rally && \
+ printf "[database]\nconnection = 'sqlite:////var/lib/rally/database/rally.sqlite'\n" > /etc/rally/rally.conf && \
+ printf "\n[openstack]\nneutron_bind_l2_agent_types = Open vSwitch agent,Linux bridge agent,OVN Controller Gateway agent\n" >> /etc/rally/rally.conf && \
+ mkdir -p /var/lib/rally/database && rally db create && \
apk del .build-deps
diff --git a/docker/core/Switch-to-threading.Thread-for-Rally-tasks.patch b/docker/core/Switch-to-threading.Thread-for-Rally-tasks.patch
new file mode 100644
index 000000000..a6d012730
--- /dev/null
+++ b/docker/core/Switch-to-threading.Thread-for-Rally-tasks.patch
@@ -0,0 +1,49 @@
+From 0d0ca00e56024a9919c150dbed62050d4c70b0c8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A9dric=20Ollivier?= <cedric.ollivier@orange.com>
+Date: Wed, 3 Jun 2020 15:23:59 +0200
+Subject: [PATCH] Switch to threading.Thread() for Rally tasks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+multiprocessing.Process() often fails due to thread crashes [1].
+It looks similar to gsutil release notes [2].
+
+[1] https://build.opnfv.org/ci/job/functest-opnfv-functest-benchmarking-cntt-latest-rally_full_cntt-run/35/console
+[2] https://github.com/GoogleCloudPlatform/gsutil/issues/548
+[3] https://github.com/GoogleCloudPlatform/gsutil/blob/master/CHANGES.md
+
+Change-Id: I582933832e23d188c7fa5999e713dd5d7e82d2da
+Signed-off-by: Cédric Ollivier <cedric.ollivier@orange.com>
+---
+ rally/task/runner.py | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/rally/task/runner.py b/rally/task/runner.py
+index 3397e1193..5edebb406 100644
+--- a/rally/task/runner.py
++++ b/rally/task/runner.py
+@@ -17,6 +17,7 @@ import abc
+ import collections
+ import copy
+ import multiprocessing
++import threading
+ import time
+
+ from rally.common import logging
+@@ -186,9 +187,9 @@ class ScenarioRunner(plugin.Plugin, validation.ValidatablePluginMixin,
+ for i in range(processes_to_start):
+ kwrgs = {"processes_to_start": processes_to_start,
+ "processes_counter": i}
+- process = multiprocessing.Process(target=worker_process,
+- args=next(worker_args_gen),
+- kwargs={"info": kwrgs})
++ process = threading.Thread(target=worker_process,
++ args=next(worker_args_gen),
++ kwargs={"info": kwrgs})
+ process.start()
+ process_pool.append(process)
+
+--
+2.26.2
+
diff --git a/docker/features/Dockerfile b/docker/features/Dockerfile
deleted file mode 100644
index a5a1b9807..000000000
--- a/docker/features/Dockerfile
+++ /dev/null
@@ -1,30 +0,0 @@
-FROM opnfv/functest-tempest
-
-ARG BRANCH=master
-ARG OPENSTACK_TAG=master
-ARG FDS_TAG=master
-
-COPY thirdparty-requirements.txt thirdparty-requirements.txt
-RUN apk --no-cache add --update python3 sshpass && \
- apk --no-cache add --virtual .build-deps --update \
- python-dev python3-dev build-base linux-headers libffi-dev \
- openssl-dev libjpeg-turbo-dev && \
- wget -q -O- https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=$OPENSTACK_TAG | \
- sed -E s/^tempest==+.*$/-e\ git+https:\\/\\/git.openstack.org\\/openstack\\/tempest#egg=tempest/ \
- > upper-constraints.txt && \
- wget -q -O- https://git.opnfv.org/functest/plain/upper-constraints.txt?h=$BRANCH | \
- sed -E /#egg=functest/d > upper-constraints.opnfv.txt && \
- git init /src/fds && \
- (cd /src/fds && \
- git fetch --tags https://gerrit.opnfv.org/gerrit/fds $FDS_TAG && \
- git checkout FETCH_HEAD) && \
- pip install --no-cache-dir --src /src -cupper-constraints.txt \
- -cupper-constraints.opnfv.txt \
- -rthirdparty-requirements.txt && \
- python3 -m pip install --no-cache-dir --src /src -cupper-constraints.txt \
- -cupper-constraints.opnfv.txt \
- -rthirdparty-requirements.txt && \
- rm -r upper-constraints.txt upper-constraints.opnfv.txt thirdparty-requirements.txt /src/fds/.git && \
- apk del .build-deps
-COPY testcases.yaml /usr/lib/python2.7/site-packages/xtesting/ci/testcases.yaml
-CMD ["run_tests", "-t", "all"]
diff --git a/docker/features/hooks/post_checkout b/docker/features/hooks/post_checkout
deleted file mode 100644
index 3e5670b4a..000000000
--- a/docker/features/hooks/post_checkout
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-from="${DOCKER_REPO%/*}/functest-tempest:${DOCKER_TAG}"
-sed -i "s|^FROM.*$|FROM ${from}|" Dockerfile
-
-exit $?
diff --git a/docker/features/testcases.yaml b/docker/features/testcases.yaml
deleted file mode 100644
index f2793fdd1..000000000
--- a/docker/features/testcases.yaml
+++ /dev/null
@@ -1,109 +0,0 @@
----
-tiers:
- -
- name: features
- order: 3
- description: >-
- Test suites from feature projects
- integrated in functest
- testcases:
- -
- case_name: doctor-notification
- project_name: doctor
- enabled: false
- criteria: 100
- blocking: false
- description: >-
- Test suite from Doctor project.
- dependencies:
- - INSTALLER_TYPE: '(apex)|(fuel)|(daisy)'
- - DEPLOY_SCENARIO: '^((?!fdio|nofeature).)*$'
- run:
- name: bashfeature
- args:
- cmd: 'doctor-test'
-
- -
- case_name: bgpvpn
- project_name: sdnvpn
- enabled: false
- criteria: 100
- blocking: false
- description: >-
- Test suite from SDNVPN project.
- dependencies:
- - DEPLOY_SCENARIO: 'bgpvpn'
- run:
- name: bgpvpn
-
- -
- case_name: functest-odl-sfc
- project_name: sfc
- enabled: false
- criteria: 100
- blocking: false
- description: >-
- Test suite for odl-sfc to test two chains with one SF and
- one chain with two SFs
- dependencies:
- - DEPLOY_SCENARIO: 'odl.*sfc'
- run:
- name: functest-odl-sfc
-
- -
- case_name: barometercollectd
- project_name: barometer
- enabled: false
- criteria: 100
- blocking: false
- description: >-
- Test suite for the Barometer project. Separate tests verify
- the proper configuration and basic functionality of all the
- collectd plugins as described in the Project Release Plan
- dependencies:
- - DEPLOY_SCENARIO: 'bar'
- run:
- name: barometercollectd
-
- -
- case_name: fds
- project_name: fastdatastacks
- enabled: false
- criteria: 100
- blocking: false
- description: >-
- Test Suite for the OpenDaylight SDN Controller when GBP
- features are installed. It integrates some test suites from
- upstream using Robot as the test framework.
- dependencies:
- - DEPLOY_SCENARIO: 'odl.*-fdio'
- run:
- name: odl
- args:
- suites:
- - /src/fds/testing/robot
- -
- case_name: vgpu
- project_name: functest
- criteria: 100
- blocking: false
- description: >-
- Test suite for the OpenStack vGPU feature
- dependencies:
- - DEPLOY_SCENARIO: 'vgpu'
- run:
- name: vgpu
-
- -
- case_name: stor4nfv_os
- project_name: stor4nfv
- enabled: false
- criteria: 100
- blocking: false
- description: >-
- This tests are necessary demonstrate conformance
- of the OpenStack+Stor4NFV deployment.
- dependencies:
- - DEPLOY_SCENARIO: 'stor4nfv'
- run:
- name: stor4nfv_os
diff --git a/docker/features/thirdparty-requirements.txt b/docker/features/thirdparty-requirements.txt
deleted file mode 100644
index 672fb24fd..000000000
--- a/docker/features/thirdparty-requirements.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-robotframework-httplibrary;python_version<'3.0'
-robotframework-requests;python_version<'3.0'
-robotframework-sshlibrary;python_version<'3.0'
-# baro_tests;python_version<'3.0'
-# sdnvpn;python_version<'3.0'
-# sfc;python_version<'3.0'
-# stor4nfv_tests;python_version<'3.0'
-# doctor-tests;python_version>='3.0'
diff --git a/docker/healthcheck/Dockerfile b/docker/healthcheck/Dockerfile
index aba2bbdee..404ff2d58 100644
--- a/docker/healthcheck/Dockerfile
+++ b/docker/healthcheck/Dockerfile
@@ -1,22 +1,15 @@
FROM opnfv/functest-core
-ARG BRANCH=master
-ARG OPENSTACK_TAG=master
-ARG ODL_TAG=85448c9d97b89989488e675b29b38ac42d8674e4
+ARG ODL_TAG=89b88a0a23561f0bda62338b394ec41655679b2d
COPY thirdparty-requirements.txt thirdparty-requirements.txt
-RUN wget -q -O- https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=$OPENSTACK_TAG | \
- sed -E s/^tempest==+\(.*\)$/-e\ git+https:\\/\\/git.openstack.org\\/openstack\\/tempest@\\1#egg=tempest/ \
- > upper-constraints.txt && \
- wget -q -O- https://git.opnfv.org/functest/plain/upper-constraints.txt?h=$BRANCH | \
- sed -E /#egg=functest/d > upper-constraints.opnfv.txt && \
- pip install --no-cache-dir --src /src -cupper-constraints.txt -cupper-constraints.opnfv.txt \
- -rthirdparty-requirements.txt && \
+RUN apk --no-cache add --virtual .build-deps --update \
+ python3-dev build-base linux-headers libffi-dev openssl-dev && \
git init /src/odl_test && \
(cd /src/odl_test && \
- git fetch --tags https://git.opendaylight.org/gerrit/p/integration/test.git $ODL_TAG && \
+ git fetch --tags https://git.opendaylight.org/gerrit/integration/test $ODL_TAG && \
git checkout FETCH_HEAD) && \
- rm -r /src/odl_test/.git thirdparty-requirements.txt upper-constraints.txt \
- upper-constraints.opnfv.txt
-COPY testcases.yaml /usr/lib/python2.7/site-packages/xtesting/ci/testcases.yaml
+ rm -r /src/odl_test/.git thirdparty-requirements.txt && \
+ apk del .build-deps
+COPY testcases.yaml /etc/xtesting/testcases.yaml
CMD ["run_tests", "-t", "all"]
diff --git a/docker/healthcheck/testcases.yaml b/docker/healthcheck/testcases.yaml
index cdb13e53b..7b6b2a108 100644
--- a/docker/healthcheck/testcases.yaml
+++ b/docker/healthcheck/testcases.yaml
@@ -2,7 +2,6 @@
tiers:
-
name: healthcheck
- order: 0
description: >-
First tier to be executed to verify the basic
operations in the VIM.
@@ -28,6 +27,8 @@ tiers:
It creates and configures all tenant network ressources
required by advanced testcases (subnet, network and
router).
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: tenantnetwork1
@@ -40,6 +41,8 @@ tiers:
It creates new user/project before creating and configuring
all tenant network ressources required by a testcase
(subnet, network and router).
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: tenantnetwork2
@@ -146,28 +149,34 @@ tiers:
- /src/odl_test/csit/suites/openstack/neutron
-
- case_name: api_check
+ case_name: tempest_smoke
project_name: functest
criteria: 100
- blocking: true
+ blocking: false
description: >-
- This test case verifies the retrieval of OpenStack clients:
- Keystone, Glance, Neutron and Nova and may perform some
- simple queries. When the config value of
- snaps.use_keystone is True, functest must have access to
- the cloud's private network.
+ This test case runs the smoke subset of the OpenStack
+ Tempest suite. The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deplopyment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L114
run:
- name: api_check
+ name: tempest_common
+ args:
+ mode: '(?=.*\[.*\bsmoke\b.*\])(^tempest\.api)'
+ option:
+ - '--concurrency=4'
-
- case_name: snaps_health_check
+ case_name: tempest_horizon
project_name: functest
criteria: 100
- blocking: true
+ blocking: false
description: >-
- This test case creates executes the SimpleHealthCheck
- Python test class which creates an, image, flavor, network,
- and Cirros VM instance and observes the console output to
- validate the single port obtains the correct IP address.
+ This test case runs the Tempest suite proposed by the
+ Horizon project.
+ dependencies:
+ - DASHBOARD_URL: '^(?!\s*$).+'
run:
- name: snaps_health_check
+ name: tempest_common
+ args:
+ mode: '^tempest.scenario.test_dashboard_basic_ops.'
diff --git a/docker/healthcheck/thirdparty-requirements.txt b/docker/healthcheck/thirdparty-requirements.txt
index 6d7ee1226..f8e37e3cb 100644
--- a/docker/healthcheck/thirdparty-requirements.txt
+++ b/docker/healthcheck/thirdparty-requirements.txt
@@ -1,3 +1,3 @@
robotframework-httplibrary
robotframework-requests
-robotframework-sshlibrary;python_version=='2.7'
+robotframework-sshlibrary
diff --git a/docker/smoke-cntt/Dockerfile b/docker/smoke-cntt/Dockerfile
new file mode 100644
index 000000000..a8e8a6f75
--- /dev/null
+++ b/docker/smoke-cntt/Dockerfile
@@ -0,0 +1,5 @@
+FROM opnfv/functest-smoke
+
+COPY testcases.yaml /etc/xtesting/testcases.yaml
+COPY tempest_conf.yaml /src/functest/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml
+CMD ["run_tests", "-t", "all"]
diff --git a/docker/smoke-cntt/tempest_conf.yaml b/docker/smoke-cntt/tempest_conf.yaml
new file mode 100644
index 000000000..d9f878992
--- /dev/null
+++ b/docker/smoke-cntt/tempest_conf.yaml
@@ -0,0 +1,104 @@
+---
+compute:
+ min_microversion: 2.44
+ max_microversion: 2.88
+compute-feature-enabled:
+ attach_encrypted_volume: false
+ block_migration_for_live_migration: false
+ block_migrate_cinder_iscsi: false
+ change_password: false
+ cold_migration: true
+ config_drive: true
+ console_output: true
+ disk_config: true
+ enable_instance_password: true
+ hostname_fqdn_sanitization: false
+ interface_attach: true
+ live_migration: true
+ live_migrate_back_and_forth: false
+ metadata_service: true
+ pause: true
+ personality: false
+ rdp_console: false
+ rescue: true
+ resize: true
+ scheduler_available_filters: "AvailabilityZoneFilter,ComputeFilter,\
+ ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,\
+ ServerGroupAffinityFilter,SameHostFilter,DifferentHostFilter"
+ serial_console: false
+ shelve: true
+ snapshot: true
+ spice_console: false
+ suspend: true
+ swap_volume: false
+ vnc_console: true
+ volume_backed_live_migration: false
+ volume_multiattach: false
+identity:
+ auth_version: v3
+ user_unique_last_password_count: 2
+ user_lockout_duration: 10
+ user_lockout_failure_attempts: 2
+identity-feature-enabled:
+ trust: true
+ api_v2: false
+ api_v2_admin: false
+ security_compliance: true
+ federation: false
+ external_idp: false
+ project_tags: true
+ application_credentials: true
+ access_rules: true
+image-feature-enabled:
+ api_v2: true
+ api_v1: false
+ import_image: false
+network-feature-enabled:
+ port_admin_state_change: true
+ port_security: true
+placement:
+ max_microversion: 1.36
+validation:
+ image_ssh_user: cirros
+ ssh_timeout: 196
+ ip_version_for_ssh: 4
+ run_validation: true
+volume:
+ max_microversion: 3.64
+ storage_protocol: ceph
+ manage_volume_ref: source-name,volume-%s
+ manage_snapshot_ref: source-name,snapshot-%s
+volume-feature-enabled:
+ multi_backend: false
+ backup: true
+ snapshot: true
+ clone: true
+ manage_snapshot: true
+ manage_volume: true
+ extend_attached_volume: true
+ extend_attached_encrypted_volume: false
+ consistency_group: false
+ volume_revert: true
+load_balancer:
+ test_with_ipv6: false
+neutron_plugin_options:
+ agent_availability_zone: nova
+ available_type_drivers: flat,geneve,vlan,gre,local,vxlan
+ provider_vlans: public,
+ create_shared_resources: true
+object-storage-feature-enabled:
+ discoverable_apis: "account_quotas,formpost,bulk_upload,bulk_delete,\
+ tempurl,crossdomain,container_quotas,staticweb,account_quotas,slo"
+ object_versioning: true
+ discoverability: true
+ tempurl_digest_hashlib: sha1
+heat_plugin:
+ skip_functional_test_list: EncryptionVolTypeTest
+ skip_scenario_test_list: "AodhAlarmTest,SoftwareConfigIntegrationTest,\
+ VolumeBackupRestoreIntegrationTest,CfnInitIntegrationTest,\
+ LoadBalancerTest"
+ auth_version: 3
+heat_features_enabled:
+ multi_cloud: false
+rbac:
+ enable_rbac: true
diff --git a/docker/smoke-cntt/testcases.yaml b/docker/smoke-cntt/testcases.yaml
new file mode 100644
index 000000000..1d2aec38b
--- /dev/null
+++ b/docker/smoke-cntt/testcases.yaml
@@ -0,0 +1,321 @@
+---
+tiers:
+ -
+ name: smoke_cntt
+ description: >-
+ Set of basic Functional tests to validate the OPNFV scenarios.
+ testcases:
+ -
+ case_name: tempest_neutron_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ deny_skipping: true
+ tests_count: 564
+ description: >-
+ This test case runs the Tempest suite proposed by the
+ Neutron project. The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
+ run:
+ name: tempest_common
+ args:
+ mode: "(?!.*admin.test_agent_availability_zone)\
+ (?!.*admin.test_dhcp_agent_scheduler)\
+ (?!.*admin.test_l3_agent_scheduler)\
+ (?!.*admin.test_logging)\
+ (?!.*admin.test_logging_negative)\
+ (?!.*admin.test_network_segment_range)\
+ (?!.*admin.test_ports.PortTestCasesAdmin.test_regenerate_mac_address)\
+ (?!.*admin.test_ports.PortTestCasesResourceRequest)\
+ (?!.*admin.test_routers_dvr)\
+ (?!.*admin.test_routers_flavors)\
+ (?!.*admin.test_routers_ha)\
+ (?!.*test_conntrack_helper)\
+ (?!.*test_floating_ips.FloatingIPPoolTestJSON)\
+ (?!.*test_floating_ips.FloatingIPTestJSON.test_create_update_floatingip_port_details)\
+ (?!.*test_local_ip)\
+ (?!.*test_metering_extensions)\
+ (?!.*test_metering_negative)\
+ (?!.*test_networks.NetworksSearchCriteriaTest.test_list_validation_filters)\
+ (?!.*test_networks.NetworksTestAdmin.test_create_tenant_network_vxlan)\
+ (?!.*test_networks.NetworksTestJSON.test_create_update_network_dns_domain)\
+ (?!.*test_port_forwarding_negative)\
+ (?!.*test_port_forwardings)\
+ (?!.*test_ports.PortsTaggingOnCreation)\
+ (?!.*test_ports.PortsTestJSON.test_create_port_with_propagate_uplink_status)\
+ (?!.*test_ports.PortsTestJSON.test_create_port_without_propagate_uplink_status)\
+ (?!.*test_ports.PortsTestJSON.test_create_update_port_with_dns_domain)\
+ (?!.*test_ports.PortsTestJSON.test_create_update_port_with_dns_name)\
+ (?!.*test_ports.PortsTestJSON.test_create_update_port_with_no_dns_name)\
+ (?!.*test_qos.QosMinimumBandwidthRuleTestJSON)\
+ (?!.*test_revisions.TestRevisions.test_update_dns_domain_bumps_revision)\
+ (?!.*test_revisions.TestRevisions.test_update_router_extra_attributes_bumps_revision)\
+ (?!.*test_router_interface_fip)\
+ (?!.*test_routers.DvrRoutersTest)\
+ (?!.*test_routers.HaRoutersTest)\
+ (?!.*test_routers.RoutersIpV6Test.test_extra_routes_atomic)\
+ (?!.*test_routers.RoutersTest.test_extra_routes_atomic)\
+ (?!.*test_routers_negative.DvrRoutersNegativeTest)\
+ (?!.*test_routers_negative.DvrRoutersNegativeTestExtended)\
+ (?!.*test_routers_negative.HaRoutersNegativeTest)\
+ (?!.*test_security_groups.RbacSharedSecurityGroupTest)\
+ (?!.*test_subnetpool_prefix_ops)\
+ (?!.*test_subnetpools.RbacSubnetPoolTest)\
+ (?!.*test_subnetpools.SubnetPoolsSearchCriteriaTest.test_list_validation_filters)\
+ (?!.*test_subnetpools_negative.SubnetPoolsNegativeTestJSON.test_tenant_create_subnetpool_associate_shared_address_scope)\
+ (?!.*test_subnets.SubnetsSearchCriteriaTest.test_list_validation_filters)\
+ (?!.*test_timestamp.TestTimeStamp.test_segment_with_timestamp)\
+ (?!.*test_trunk.TrunkTestInheritJSONBase.test_add_subport)\
+ (?!.*test_trunk.TrunkTestMtusJSON)\
+ (?!.*test_trunk_negative.TrunkTestJSON.test_create_subport_invalid_inherit_network_segmentation_type)\
+ (?!.*test_trunk_negative.TrunkTestMtusJSON)\
+ (^neutron_tempest_plugin.api)"
+ option:
+ - '--concurrency=4'
+
+ -
+ case_name: tempest_cinder_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ deny_skipping: true
+ tests_count: 10
+ description: >-
+ This test case runs the Tempest suite proposed by the
+ Cinder project.
+ run:
+ name: tempest_common
+ args:
+ mode: "(?!.*test_incremental_backup)\
+ (?!.*test_consistencygroups)\
+ (?!.*test_backup_crossproject_admin_negative)\
+ (?!.*test_backup_crossproject_user_negative)\
+ (?!.*test_volume_encrypted.TestEncryptedCinderVolumes)\
+ (?!.*rbac)\
+ (^cinder_tempest_plugin.)"
+ option:
+ - '--concurrency=4'
+
+ -
+ case_name: tempest_keystone_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ deny_skipping: true
+ tests_count: 27
+ description: >-
+ This test case runs the Tempest suite proposed by the
+ Keystone project.
+ run:
+ name: tempest_common
+ args:
+ mode: "(?!.*api.identity.v3.test_oauth1_tokens)\
+ (?!.*rbac)\
+ (?!.*scenario.test_federated_authentication)\
+ keystone_tempest_plugin."
+ option:
+ - '--concurrency=4'
+
+ -
+ case_name: tempest_heat_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ deny_skipping: true
+ tests_count: 124
+ description: >-
+ This test case runs the Tempest suite proposed by the
+ Heat project.
+ run:
+ name: tempest_heat
+ args:
+ mode: "(?!.*functional.test_lbaasv2)\
+ (?!.*functional.test_encryption_vol_type)\
+ (?!.*functional.test_event_sinks)\
+ (?!.*functional.test_software_config.ZaqarSignalTransportTest)\
+ (?!.*functional.test_stack_events)\
+ (?!.*functional.test_waitcondition)\
+ (?!.*RemoteStackTest.test_stack_create_with_cloud_credential)\
+ (?!.*scenario.test_aodh_alarm)\
+ (?!.*tests.scenario.test_autoscaling_lb)\
+ (?!.*scenario.test_autoscaling_lbv2)\
+ (?!.*scenario.test_server_software_config)\
+ (?!.*test_volumes.VolumeBackupRestoreIntegrationTest)\
+ (?!.*scenario.test_octavia_lbaas)\
+ (?!.*scenario.test_server_cfn_init)\
+ ^heat_tempest_plugin.tests"
+ option:
+ - '--concurrency=1'
+
+ -
+ case_name: rally_sanity_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs a sub group of tests of the OpenStack
+ Rally suite in smoke mode.
+ run:
+ name: rally_sanity
+ args:
+ tests:
+ - 'authenticate'
+ - 'glance'
+ - 'cinder'
+ - 'heat'
+ - 'keystone'
+ - 'neutron'
+ - 'nova'
+ - 'quotas'
+ - 'swift'
+
+ -
+ case_name: tempest_full_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ deny_skipping: true
+ tests_count: 1271
+ description: >-
+ The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L83
+ run:
+ name: tempest_common
+ args:
+ mode: "(?!.*admin.test_agents)(?!.*test_fixed_ips)\
+ (?!.*test_fixed_ips_negative)\
+ (?!.*test_auto_allocate_network)(?!.*test_floating_ips_bulk)\
+ (?!.*test_flavors_microversions.FlavorsV255TestJSON)\
+ (?!.*test_flavors_microversions.FlavorsV261TestJSON)\
+ (?!.*test_live_migration.LiveAutoBlockMigrationV225Test.test_iscsi_volume)\
+ (?!.*test_live_migration.LiveAutoBlockMigrationV225Test.test_live_block_migration)\
+ (?!.*test_live_migration.LiveAutoBlockMigrationV225Test.test_live_block_migration_paused)\
+ (?!.*test_live_migration.LiveAutoBlockMigrationV225Test.test_volume_backed_live_migration)\
+ (?!.*test_live_migration.LiveMigrationTest.test_iscsi_volume)\
+ (?!.*test_live_migration.LiveMigrationTest.test_live_block_migration)\
+ (?!.*test_live_migration.LiveMigrationTest.test_live_block_migration_paused)\
+ (?!.*test_live_migration.LiveMigrationTest.test_volume_backed_live_migration)\
+ (?!.*test_live_migration.LiveMigrationRemoteConsolesV26Test)\
+ (?!.*test_quotas.QuotasAdminTestV257)\
+ (?!.*test_servers.ServersAdminTestJSON.test_reset_network_inject_network_info)\
+ (?!.*certificates.test_certificates)\
+ (?!.*test_quotas_negative.QuotasSecurityGroupAdminNegativeTest)\
+ (?!.*test_novnc)(?!.*test_server_personality)\
+ (?!.*test_servers.ServerShowV263Test.test_show_update_rebuild_list_server)\
+ (?!.*test_servers_microversions.ServerShowV254Test)\
+ (?!.*test_servers_microversions.ServerShowV257Test)\
+ (?!.*test_servers_negative.ServersNegativeTestJSON.test_personality_file_contents_not_encoded)\
+ (?!.*servers.test_virtual_interfaces)\
+ (?!.*test_server_actions.ServerActionsTestJSON.test_change_server_password)\
+ (?!.*test_server_actions.ServerActionsTestJSON.test_get_vnc_console)\
+ (?!.*test_server_actions.ServerActionsTestJSON.test_reboot_server_soft)\
+ (?!.*test_server_rescue.ServerBootFromVolumeStableRescueTest)\
+ (?!.*test_server_rescue.ServerStableDeviceRescueTest)\
+ (?!.*test_security_group_default_rules)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_security_group_create_with_duplicate_name)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_security_group_create_with_invalid_group_description)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_security_group_create_with_invalid_group_name)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_update_security_group_with_invalid_sg_des)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_update_security_group_with_invalid_sg_id)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_update_security_group_with_invalid_sg_name)\
+ (?!.*test_create_server.ServersTestFqdnHostnames.test_create_server_with_fqdn_name)\
+ (?!.*test_server_metadata.ServerMetadataTestJSON)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_delete_metadata_non_existent_server)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_metadata_items_limit)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_set_metadata_invalid_key)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_set_metadata_non_existent_server)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_set_server_metadata_blank_key)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_set_server_metadata_missing_metadata)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_update_metadata_non_existent_server)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_update_metadata_with_blank_key)\
+ (?!.*test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filtered_by_ip_regex)\
+ (?!.*compute.test_virtual_interfaces)(?!.*compute.test_virtual_interfaces_negative)\
+ (?!.*compute.test_networks)\
+ (?!.*test_attach_volume.AttachVolumeMultiAttach)\
+ (?!.*identity.admin.v2)(?!.*identity.v2)\
+ (?!.*identity.v3.test_access_rules)\
+ (?!.*identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_create_application_credential_access_rules)\
+ (?!.*image.v1)\
+ (?!.*image.v2.admin.test_images.ImportCopyImagesTest)\
+ (?!.*image.v2.test_images_negative.ImagesNegativeTest.test_create_image_reserved_property)\
+ (?!.*image.v2.test_images_negative.ImagesNegativeTest.test_update_image_reserved_property)\
+ (?!.*image.v2.test_images_negative.ImportImagesNegativeTest.test_image_web_download_import_with_bad_url)\
+ (?!.*image.v2.test_images.ImportImagesTest)\
+ (?!.*image.v2.test_images.MultiStoresImportImages)\
+ (?!.*admin.test_dhcp_agent_scheduler)\
+ (?!.*admin.test_routers_dvr)\
+ (?!.*test_metering_extensions)(?!.*network.test_tags)\
+ (?!.*test_routers_negative.DvrRoutersNegativeTest)\
+ (?!.*test_routers.RoutersIpV6Test.test_create_router_set_gateway_with_fixed_ip)\
+ (?!.*test_routers.RoutersTest.test_create_router_set_gateway_with_fixed_ip)\
+ (?!.*test_object_services.ObjectTest.test_create_object_with_transfer_encoding)\
+ (?!.*test_encrypted_volumes_extend)\
+ (?!.*test_group_snapshots.GroupSnapshotsV319Test.test_reset_group_snapshot_status)\
+ (?!.*test_multi_backend)\
+ (?!.*test_volume_retype.VolumeRetypeWithMigrationTest)\
+ (?!.*test_volume_delete_cascade.VolumesDeleteCascade.test_volume_from_snapshot_cascade_delete)\
+ (?!.*test_volumes_backup.VolumesBackupsTest.test_volume_backup_create_get_detailed_list_restore_delete)\
+ (?!.*test_volumes_negative.UpdateMultiattachVolumeNegativeTest.test_multiattach_rw_volume_update_failure)\
+ (?!.*test_volumes_extend.VolumesExtendAttachedTest.test_extend_attached_volume)\
+ (?!.*\\[.*\\bslow\\b.*\\])(^tempest.api)"
+ option:
+ - '--concurrency=4'
+
+ -
+ case_name: tempest_scenario_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ deny_skipping: true
+ tests_count: 13
+ description: >-
+ The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L84
+ run:
+ name: tempest_common
+ args:
+ mode: "\
+ (?!.*test_compute_unified_limits)\
+ (?!.*test_minbw_allocation_placement)\
+ (?!.*test_network_qos_placement)\
+ (?!.*test_unified_limits.ImageQuotaTest.test_image_count_uploading_quota)\
+ (?!.*test_unified_limits.ImageQuotaTest.test_image_stage_quota)\
+ (?!.*test_volume_boot_pattern.TestVolumeBootPattern.test_boot_server_from_encrypted_volume_luks)\
+ (?!.*\\[.*\\bslow\\b.*\\])(^tempest.scenario)"
+ option:
+ - '--concurrency=1'
+
+ -
+ case_name: tempest_slow_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ deny_skipping: true
+ tests_count: 43
+ description: >-
+ The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L84
+ run:
+ name: tempest_common
+ args:
+ mode: "(?!.*test_volume_swap)\
+ (?!.*test_server_personality)\
+ (?!.*test_server_rescue.ServerBootFromVolumeStableRescueTest)\
+ (?!.*test_container_sync.ContainerSyncTest.test_container_synchronization)\
+ (?!.*test_container_sync_middleware.ContainerSyncMiddlewareTest.test_container_synchronization)\
+ (?!.*test_encrypted_cinder_volumes)\
+ (?!.*test_minbw_allocation_placement)\
+ (?!.*test_network_basic_ops.TestNetworkBasicOps.test_router_rescheduling)\
+ (?!.*test_shelve_instance.TestShelveInstance.test_cold_migrate_unshelved_instance)\
+ (?!.*test_volume_migrate_attached)\
+ (?!.*test_network_advanced_server_ops.TestNetworkAdvancedServerOps.test_server_connectivity_cold_migration_revert)\
+ (?=.*\\[.*\\bslow\\b.*\\])(^tempest.)"
+ option:
+ - '--concurrency=1'
diff --git a/docker/smoke/Dockerfile b/docker/smoke/Dockerfile
index 19fa9d9c1..da42ef9b4 100644
--- a/docker/smoke/Dockerfile
+++ b/docker/smoke/Dockerfile
@@ -1,52 +1,94 @@
-FROM opnfv/functest-tempest
+FROM opnfv/functest-core
-ARG BRANCH=master
-ARG OPENSTACK_TAG=master
-ARG REFSTACK_TARGET=2018.02
-ARG PATROLE_TAG=0.4.0
+ARG PATROLE_TAG=master
+ARG NEUTRON_TEMPEST_TAG=master
+ARG CINDER_TEMPEST_TAG=master
+ARG KEYSTONE_TEMPEST_TAG=master
ARG NEUTRON_TAG=master
-ARG BARBICAN_TAG=0.1.0
-ARG NEUTRON_RALLY_TAG=master
+ARG GLANCE_TAG=master
+ARG NOVA_TAG=master
+ARG KEYSTONE_TAG=master
+ARG CINDER_TAG=master
+ARG BARBICAN_TAG=master
+ARG OCTAVIA_TAG=master
+ARG HEAT_TEMPEST_TAG=master
+ARG TELEMETRY_TEMPEST_TAG=master
+ARG CYBORG_TEMPEST_TAG=master
-RUN apk --no-cache add --virtual .build-deps --update \
- python-dev build-base linux-headers libffi-dev \
- openssl-dev libjpeg-turbo-dev && \
- wget -q -O- https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=$OPENSTACK_TAG | \
- sed -E s/^tempest==+.*$/-e\ git+https:\\/\\/git.openstack.org\\/openstack\\/tempest#egg=tempest/ \
- > upper-constraints.txt && \
- wget -q -O- https://git.opnfv.org/functest/plain/upper-constraints.txt?h=$BRANCH | \
- sed -E /#egg=functest/d > upper-constraints.opnfv.txt && \
+RUN apk --no-cache add --update libxml2 libxslt && \
+ apk --no-cache add --virtual .build-deps --update \
+ python3-dev build-base linux-headers libffi-dev \
+ openssl-dev libjpeg-turbo-dev libxml2-dev libxslt-dev && \
+ case $(uname -m) in aarch*|arm*) CFLAGS="-O0" \
+ pip3 install --use-deprecated=legacy-resolver --no-cache-dir -c/src/requirements/upper-constraints.txt \
+ -c/src/functest/upper-constraints.txt lxml && \
+ sed -i -E /^numpy=/d /src/requirements/upper-constraints.txt && apk add py3-numpy ;; esac && \
git init /src/patrole && \
(cd /src/patrole && \
- git fetch --tags https://git.openstack.org/openstack/patrole.git $PATROLE_TAG && \
+ git fetch --tags https://opendev.org/openstack/patrole.git $PATROLE_TAG && \
git checkout FETCH_HEAD) && \
- update-requirements -s --source /src/openstack-requirements /src/patrole/ && \
+ update-requirements -s --source /src/requirements /src/patrole/ && \
git init /src/neutron-tempest-plugin && \
(cd /src/neutron-tempest-plugin && \
- git fetch --tags https://git.openstack.org/openstack/neutron-tempest-plugin.git $NEUTRON_TAG && \
+ git fetch --tags https://opendev.org/openstack/neutron-tempest-plugin.git $NEUTRON_TEMPEST_TAG && \
git checkout FETCH_HEAD) && \
- update-requirements -s --source /src/openstack-requirements /src/neutron-tempest-plugin && \
+ update-requirements -s --source /src/requirements /src/neutron-tempest-plugin && \
+ git init /src/cinder-tempest-plugin && \
+ (cd /src/cinder-tempest-plugin && \
+ git fetch --tags https://opendev.org/openstack/cinder-tempest-plugin.git $CINDER_TEMPEST_TAG && \
+ git checkout FETCH_HEAD) && \
+ update-requirements -s --source /src/requirements /src/cinder-tempest-plugin && \
+ git init /src/keystone-tempest-plugin && \
+ (cd /src/keystone-tempest-plugin && \
+ git fetch --tags https://opendev.org/openstack/keystone-tempest-plugin.git $KEYSTONE_TEMPEST_TAG && \
+ git checkout FETCH_HEAD) && \
+ update-requirements -s --source /src/requirements /src/keystone-tempest-plugin && \
git init /src/barbican-tempest-plugin && \
(cd /src/barbican-tempest-plugin && \
- git fetch --tags https://git.openstack.org/openstack/barbican-tempest-plugin.git $BARBICAN_TAG && \
+ git fetch --tags https://opendev.org/openstack/barbican-tempest-plugin.git $BARBICAN_TAG && \
+ git checkout FETCH_HEAD) && \
+ update-requirements -s --source /src/requirements /src/barbican-tempest-plugin/ && \
+ git init /src/octavia-tempest-plugin && \
+ (cd /src/octavia-tempest-plugin && \
+ git fetch --tags https://opendev.org/openstack/octavia-tempest-plugin.git $OCTAVIA_TAG && \
+ git checkout FETCH_HEAD) && \
+ update-requirements -s --source /src/requirements /src/octavia-tempest-plugin && \
+ git init /src/heat-tempest-plugin && \
+ (cd /src/heat-tempest-plugin && \
+ git fetch --tags https://opendev.org/openstack/heat-tempest-plugin.git $HEAT_TEMPEST_TAG && \
+ git checkout FETCH_HEAD) && \
+ update-requirements -s --source /src/requirements /src/heat-tempest-plugin && \
+ git init /src/telemetry-tempest-plugin && \
+ (cd /src/telemetry-tempest-plugin && \
+ git fetch --tags https://opendev.org/openstack/telemetry-tempest-plugin.git $TELEMETRY_TEMPEST_TAG && \
+ git checkout FETCH_HEAD) && \
+ update-requirements -s --source /src/requirements /src/telemetry-tempest-plugin && \
+ git init /src/cyborg-tempest-plugin && \
+ (cd /src/cyborg-tempest-plugin && \
+ git fetch --tags https://opendev.org/openstack/cyborg-tempest-plugin.git $CYBORG_TEMPEST_TAG && \
git checkout FETCH_HEAD) && \
- update-requirements -s --source /src/openstack-requirements /src/barbican-tempest-plugin/ && \
- pip install --no-cache-dir --src /src -cupper-constraints.txt -cupper-constraints.opnfv.txt \
+ update-requirements -s --source /src/requirements /src/cyborg-tempest-plugin && \
+ pip3 install --use-deprecated=legacy-resolver --no-cache-dir --src /src -c/src/requirements/upper-constraints.txt \
+ -c/src/functest/upper-constraints.txt \
/src/patrole /src/barbican-tempest-plugin /src/neutron-tempest-plugin \
- networking-bgpvpn networking-sfc && \
- rm -r upper-constraints.txt upper-constraints.opnfv.txt \
- /src/patrole /src/barbican-tempest-plugin /src/neutron-tempest-plugin && \
+ /src/cinder-tempest-plugin /src/keystone-tempest-plugin \
+ /src/octavia-tempest-plugin /src/heat-tempest-plugin /src/telemetry-tempest-plugin \
+ /src/cyborg-tempest-plugin && \
mkdir -p /home/opnfv/functest/data/refstack && \
- wget "https://refstack.openstack.org/api/v1/guidelines/${REFSTACK_TARGET}/tests?target=compute&type=required&alias=true&flag=false" \
- -O /home/opnfv/functest/data/refstack/defcore.txt && \
- mkdir -p /etc/neutron /etc/glance && \
- wget -q -O /etc/neutron/policy.json https://git.openstack.org/cgit/openstack/neutron/plain/etc/policy.json?h=$OPENSTACK_TAG && \
- wget -q -O /etc/glance/policy.json https://git.openstack.org/cgit/openstack/glance/plain/etc/policy.json?h=$OPENSTACK_TAG && \
- git clone --depth 1 -b $NEUTRON_RALLY_TAG https://git.openstack.org/openstack/neutron.git /src/neutron && \
- (cd /src/neutron && git fetch --tags origin $NEUTRON_RALLY_TAG && git checkout FETCH_HEAD) && \
- mkdir -p /home/opnfv/functest/data/rally/neutron && \
- cp -r /src/neutron/rally-jobs /home/opnfv/functest/data/rally/neutron/rally-jobs && \
- rm -r /src/neutron && \
+ pip3 install --use-deprecated=legacy-resolver --no-cache-dir --src /src -c/src/requirements/upper-constraints.txt \
+ -c/src/functest/upper-constraints.txt \
+ git+https://opendev.org/openstack/neutron.git@$NEUTRON_TAG#egg=neutron \
+ git+https://opendev.org/openstack/glance.git@$GLANCE_TAG#egg=glance \
+ git+https://opendev.org/openstack/nova.git@$NOVA_TAG#egg=nova \
+ git+https://opendev.org/openstack/keystone.git@$KEYSTONE_TAG#egg=keystone \
+ git+https://opendev.org/openstack/cinder.git@$CINDER_TAG#egg=cinder && \
+ rm -r /src/patrole /src/barbican-tempest-plugin /src/neutron-tempest-plugin \
+ /src/cinder-tempest-plugin /src/keystone-tempest-plugin \
+ /src/octavia-tempest-plugin /src/heat-tempest-plugin \
+ /src/telemetry-tempest-plugin /src/cyborg-tempest-plugin && \
apk del .build-deps
-COPY testcases.yaml /usr/lib/python2.7/site-packages/xtesting/ci/testcases.yaml
+COPY compute.txt /home/opnfv/functest/data/refstack/compute.txt
+COPY object.txt /home/opnfv/functest/data/refstack/object.txt
+COPY platform.txt /home/opnfv/functest/data/refstack/platform.txt
+COPY testcases.yaml /etc/xtesting/testcases.yaml
CMD ["run_tests", "-t", "all"]
diff --git a/docker/smoke/compute.txt b/docker/smoke/compute.txt
new file mode 100644
index 000000000..7a642a703
--- /dev/null
+++ b/docker/smoke/compute.txt
@@ -0,0 +1,368 @@
+tempest.api.compute.flavors.test_flavors.FlavorsV2TestJSON.test_list_flavors[id-e36c0eaa-dff5-4082-ad1f-3f9a80aa3f59]
+tempest.api.compute.flavors.test_flavors.FlavorsV2TestJSON.test_list_flavors_with_detail[id-6e85fde4-b3cd-4137-ab72-ed5f418e8c24]
+tempest.api.compute.images.test_images_oneserver.ImagesOneServerTestJSON.test_create_delete_image[id-3731d080-d4c5-4872-b41a-64d0d0021314]
+tempest.api.compute.images.test_images_oneserver.ImagesOneServerTestJSON.test_create_image_specify_multibyte_character_image_name[id-3b7c6fe4-dfe7-477c-9243-b06359db51e6]
+tempest.api.compute.keypairs.test_keypairs_v22.KeyPairsV22TestJSON.test_keypairsv22_create_list_show_with_type[id-89d59d43-f735-441a-abcf-0601727f47b6]
+tempest.api.compute.security_groups.test_security_groups.SecurityGroupsTestJSON.test_list_security_groups_by_server[id-79517d60-535a-438f-af3d-e6feab1cbea7]
+tempest.api.compute.security_groups.test_security_groups.SecurityGroupsTestJSON.test_security_group_create_get_delete[id-ecc0da4a-2117-48af-91af-993cca39a615]
+tempest.api.compute.security_groups.test_security_groups.SecurityGroupsTestJSON.test_security_groups_create_list_delete[id-eb2b087d-633d-4d0d-a7bd-9e6ba35b32de]
+tempest.api.compute.security_groups.test_security_groups.SecurityGroupsTestJSON.test_server_security_groups[id-fe4abc0d-83f5-4c50-ad11-57a1127297a2]
+tempest.api.compute.security_groups.test_security_groups.SecurityGroupsTestJSON.test_update_security_groups[id-7d4e1d3c-3209-4d6d-b020-986304ebad1f]
+tempest.api.compute.security_groups.test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_delete_nonexistent_security_group[id-6727c00b-214c-4f9e-9a52-017ac3e98411]
+tempest.api.compute.security_groups.test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_delete_security_group_without_passing_id[id-1438f330-8fa4-4aeb-8a94-37c250106d7f]
+tempest.api.compute.security_groups.test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_delete_the_default_security_group[id-36a1629f-c6da-4a26-b8b8-55e7e5d5cd58]
+tempest.api.compute.security_groups.test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_security_group_get_nonexistent_group[id-673eaec1-9b3e-48ed-bdf1-2786c1b9661c]
+tempest.api.compute.security_groups.test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_update_non_existent_security_group[id-27edee9c-873d-4da6-a68a-3c256efebe8f]
+tempest.api.compute.servers.test_availability_zone.AZV2TestJSON.test_get_availability_zone_list_with_non_admin_user[id-a8333aa2-205c-449f-a828-d38c2489bf25]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_host_name_is_same_as_server_name[id-ac1ad47f-984b-4441-9274-c9079b7a0666]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_list_servers[id-9a438d88-10c6-4bcd-8b5b-5b6e25e1346f]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_list_servers_with_detail[id-585e934c-448e-43c4-acbf-d06a9b899997]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_verify_created_server_vcpus[id-cbc0f52f-05aa-492b-bdc1-84b575ca294b]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_verify_server_details[id-5de47127-9977-400a-936f-abcfbec1218f]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_host_name_is_same_as_server_name[id-ac1ad47f-984b-4441-9274-c9079b7a0666]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers[id-9a438d88-10c6-4bcd-8b5b-5b6e25e1346f]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers_with_detail[id-585e934c-448e-43c4-acbf-d06a9b899997]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_created_server_vcpus[id-cbc0f52f-05aa-492b-bdc1-84b575ca294b]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_server_details[id-5de47127-9977-400a-936f-abcfbec1218f]
+tempest.api.compute.servers.test_delete_server.DeleteServersTestJSON.test_delete_active_server[id-925fdfb4-5b13-47ea-ac8a-c36ae6fddb05]
+tempest.api.compute.servers.test_instance_actions.InstanceActionsTestJSON.test_get_instance_action[id-aacc71ca-1d70-4aa5-bbf6-0ff71470e43c]
+tempest.api.compute.servers.test_instance_actions.InstanceActionsTestJSON.test_list_instance_actions[id-77ca5cc5-9990-45e0-ab98-1de8fead201a]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_flavor[id-80c574cc-0925-44ba-8602-299028357dd9]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_image[id-b3304c3b-97df-46d2-8cd3-e2b6659724e7]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_server_name[id-f9eb2b70-735f-416c-b260-9914ac6181e4]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_server_status[id-de2612ab-b7dd-4044-b0b1-d2539601911f]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_limit_results[id-67aec2d0-35fe-4503-9f92-f13272b867ed]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_active_status[id-ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_flavor[id-573637f5-7325-47bb-9144-3476d0416908]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_image[id-05e8a8e7-9659-459a-989d-92c2f501f4ba]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_limit[id-614cdfc1-d557-4bac-915b-3e67b48eee76]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_server_name[id-9b067a7b-7fee-4f6a-b29c-be43fe18fc5a]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_server_status[id-ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filtered_by_ip_regex[id-a905e287-c35e-42f2-b132-d02b09f3654a]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filtered_by_name_wildcard[id-e9f624ee-92af-4562-8bec-437945a18dcb]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_changes_since_future_date[id-74745ad8-b346-45b5-b9b8-509d7447fc1f]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_changes_since_invalid_date[id-87d12517-e20a-4c9c-97b6-dd1628d6d6c9]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_greater_than_actual_count[id-d47c17fb-eebd-4287-8e95-f20a7e627b18]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_pass_negative_value[id-62610dd9-4713-4ee0-8beb-fd2c1aa7f950]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_pass_string[id-679bc053-5e70-4514-9800-3dfab1a380a6]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_flavor[id-5913660b-223b-44d4-a651-a0fbfd44ca75]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_image[id-ff01387d-c7ad-47b4-ae9e-64fa214638fe]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_server_name[id-e2c77c4a-000a-4af3-a0bd-629a328bde7c]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_detail_server_is_deleted[id-93055106-2d34-46fe-af68-d9ddbf7ee570]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_status_non_existing[id-fcdf192d-0f74-4d89-911f-1ec002b822c4]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_with_a_deleted_server[id-24a26f1a-1ddc-4eea-b0d7-a90cc874ad8f]
+tempest.api.compute.servers.test_multiple_create.MultipleCreateTestJSON.test_multiple_create[id-61e03386-89c3-449c-9bb1-a06f423fd9d1]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_lock_unlock_server[id-80a8094c-211e-440a-ab88-9e59d556c7ee]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_hard[id-2cb1baf6-ac8d-4429-bf0d-ba8a0ba53e32]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_rebuild_server[id-aaa6cdf3-55a7-461a-add9-1c8596b9a07c]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_stop_start_server[id-af8eafd4-38a7-4a4b-bdbc-75145a580560]
+tempest.api.compute.servers.test_server_tags.ServerTagsTestJSON.test_check_tag_existence[id-81279a66-61c3-4759-b830-a2dbe64cbe08]
+tempest.api.compute.servers.test_server_tags.ServerTagsTestJSON.test_create_delete_tag[id-8d95abe2-c658-4c42-9a44-c0258500306b]
+tempest.api.compute.servers.test_server_tags.ServerTagsTestJSON.test_delete_all_tags[id-a63b2a74-e918-4b7c-bcab-10c855f3a57e]
+tempest.api.compute.servers.test_server_tags.ServerTagsTestJSON.test_update_all_tags[id-a2c1af8c-127d-417d-974b-8115f7e3d831]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_server_with_admin_password[id-b92d5ec7-b1dd-44a2-87e4-45e888c46ef0]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_specify_keypair[id-f9e15296-d7f9-4e62-b53f-a04e89160833]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_with_existing_server_name[id-8fea6be7-065e-47cf-89b8-496e6f96c699]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_update_access_server_address[id-89b90870-bc13-4b73-96af-f9d4f2b70077]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_update_server_name[id-5e6ccff8-349d-4852-a8b3-055df7988dd2]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_numeric_server_name[id-fd57f159-68d6-4c2a-902b-03070828a87e]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_server_metadata_exceeds_length_limit[id-7fc74810-0bd2-4cd7-8244-4f33a9db865a]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_server_name_length_exceeds_256[id-c3e0fb12-07fc-4d76-a22e-37409887afe8]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_flavor[id-18f5227f-d155-4429-807c-ccb103887537]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_image[id-fcba1052-0a50-4cf3-b1ac-fae241edf02f]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_network_uuid[id-4e72dc2d-44c5-4336-9667-f7972e95c402]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_delete_server_pass_id_exceeding_length_limit[id-f4d7279b-5fd2-4bf2-9ba4-ae35df0d18c5]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_delete_server_pass_negative_id[id-75f79124-277c-45e6-a373-a1d6803f4cc4]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_get_non_existent_server[id-3436b02f-1b1e-4f03-881e-c6a602327439]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_invalid_ip_v6_address[id-5226dd80-1e9c-4d8a-b5f9-b26ca4763fd0]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server[id-d4c023a0-9c55-4747-9dd5-413b820143c7]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_deleted_server[id-98fa0458-1485-440f-873b-fe7f0d714930]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_non_existent_server[id-d86141a7-906e-4731-b187-d64a2ea61422]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_reboot_deleted_server[id-98fa0458-1485-440f-873b-fe7f0d714930]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_server_name_blank[id-dbbfd247-c40c-449e-8f6c-d2aa7c7da7cf]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_stop_non_existent_server[id-a31460a9-49e1-42aa-82ee-06e0bb7c2d03]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_name_of_non_existent_server[id-aa8eed43-e2cb-4ebf-930b-da14f6a21d81]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_server_name_length_exceeds_256[id-5c8e244c-dada-4590-9944-749c455b431f]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_server_set_empty_name[id-38204696-17c6-44da-9590-40f87fb5a899]
+tempest.api.compute.test_quotas.QuotasTestJSON.test_get_default_quotas[id-9bfecac7-b966-4f47-913f-1a9e2c12134a]
+tempest.api.compute.test_quotas.QuotasTestJSON.test_get_quotas[id-f1ef0a97-dbbb-4cca-adc5-c9fbc4f76107]
+tempest.api.compute.test_versions.TestVersions.test_list_api_versions[id-6c0a0990-43b6-4529-9b61-5fd8daf7c55c]
+tempest.api.compute.volumes.test_attach_volume.AttachVolumeTestJSON.test_attach_detach_volume[id-52e9045a-e90d-4c0d-9087-79d657faffff]
+tempest.api.compute.volumes.test_attach_volume.AttachVolumeTestJSON.test_list_get_volume_attachments[id-7fa563fe-f0f7-43eb-9e22-a1ece036b513]
+tempest.api.identity.v3.TestApiDiscovery.test_api_media_types[id-657c1970-4722-4189-8831-7325f3bc4265]
+tempest.api.identity.v3.TestApiDiscovery.test_api_version_resources[id-b9232f5e-d9e5-4d97-b96c-28d3db4de1bd]
+tempest.api.identity.v3.TestApiDiscovery.test_api_version_statuses[id-8879a470-abfb-47bb-bb8d-5a7fd279ad1e]
+tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_media_types[id-657c1970-4722-4189-8831-7325f3bc4265]
+tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_version_resources[id-b9232f5e-d9e5-4d97-b96c-28d3db4de1bd]
+tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_version_statuses[id-8879a470-abfb-47bb-bb8d-5a7fd279ad1e]
+tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_list_api_versions[id-721f480f-35b6-46c7-846e-047e6acea0dc]
+tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_create_application_credential[id-8080c75c-eddc-4786-941a-c2da7039ae61]
+tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_create_application_credential_expires[id-852daf0c-42b5-4239-8466-d193d0543ed3]
+tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_list_application_credentials[id-ff0cd457-6224-46e7-b79e-0ada4964a8a6]
+tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_query_application_credentials[id-9bb5e5cc-5250-493a-8869-8b665f6aa5f6]
+tempest.api.identity.v3.test_catalog.IdentityCatalogTest.test_catalog_standardization[id-56b57ced-22b8-4127-9b8a-565dfb0207e2]
+tempest.api.identity.v3.test_domains.DefaultDomainTestJSON.test_default_domain_exists[id-17a5de24-e6a0-4e4a-a9ee-d85b6e5612b5]
+tempest.api.identity.v3.test_tokens.TokensV3Test.test_create_token[id-6f8e4436-fc96-4282-8122-e41df57197a9]
+tempest.api.identity.v3.test_tokens.TokensV3Test.test_token_auth_creation_existence_deletion[id-0f9f5a5f-d5cd-4a86-8a5b-c5ded151f212]
+tempest.api.identity.v3.test_tokens.TokensV3Test.test_validate_token[id-a9512ac3-3909-48a4-b395-11f438e16260]
+tempest.api.identity.v3.test_users.IdentityV3UsersTest.test_password_history_check_self_service_api[id-941784ee-5342-4571-959b-b80dd2cea516]
+tempest.api.identity.v3.test_users.IdentityV3UsersTest.test_user_account_lockout[id-a7ad8bbf-2cff-4520-8c1d-96332e151658]
+tempest.api.image.v2.test_images.BasicOperationsImagesTest.test_delete_image[id-f848bb94-1c6e-45a4-8726-39e3a5b23535]
+tempest.api.image.v2.test_images.BasicOperationsImagesTest.test_register_upload_get_image_file[id-139b765e-7f3d-4b3d-8b37-3ca3876ee318]
+tempest.api.image.v2.test_images.BasicOperationsImagesTest.test_update_image[id-f66891a7-a35c-41a8-b590-a065c2a1caa6]
+tempest.api.image.v2.test_images.ListImagesTest.test_get_image_schema[id-622b925c-479f-4736-860d-adeaf13bc371]
+tempest.api.image.v2.test_images.ListImagesTest.test_get_images_schema[id-25c8d7b2-df21-460f-87ac-93130bcdc684]
+tempest.api.image.v2.test_images.ListImagesTest.test_index_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_container_format[id-9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_disk_format[id-4a4735a7-f22f-49b6-b0d9-66e1ef7453eb]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_limit[id-e914a891-3cc8-4b40-ad32-e0a39ffbddbb]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_min_max_size[id-4ad8c157-971a-4ba8-aa84-ed61154b1e7f]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_size[id-cf1b9a48-8340-480e-af7b-fe7e17690876]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_status[id-7fc9e369-0f58-4d05-9aa5-0969e2d59d15]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_visibility[id-7a95bb92-d99e-4b12-9718-7bc6ab73e6d2]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_get_image_schema[id-622b925c-479f-4736-860d-adeaf13bc371]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_get_images_schema[id-25c8d7b2-df21-460f-87ac-93130bcdc684]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_container_format[id-9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_disk_format[id-4a4735a7-f22f-49b6-b0d9-66e1ef7453eb]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_limit[id-e914a891-3cc8-4b40-ad32-e0a39ffbddbb]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_min_max_size[id-4ad8c157-971a-4ba8-aa84-ed61154b1e7f]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_size[id-cf1b9a48-8340-480e-af7b-fe7e17690876]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_status[id-7fc9e369-0f58-4d05-9aa5-0969e2d59d15]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_visibility[id-7a95bb92-d99e-4b12-9718-7bc6ab73e6d2]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_delete_image_null_id[id-32248db1-ab88-4821-9604-c7c369f1f88c]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_delete_non_existing_image[id-6fe40f1c-57bd-4918-89cc-8500f850f3de]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_delete_deleted_image[id-e57fc127-7ba0-4693-92d7-1d8a05ebcba9]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_image_null_id[id-ef45000d-0a72-4781-866d-4cb7bf2562ad]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_non_existent_image[id-668743d5-08ad-4480-b2b8-15da34f81d9f]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_register_with_invalid_container_format[id-292bd310-369b-41c7-a7a3-10276ef76753]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_register_with_invalid_disk_format[id-70c6040c-5a97-4111-9e13-e73665264ce1]
+tempest.api.image.v2.test_images_tags.ImagesTagsTest.test_update_delete_tags_for_image[id-10407036-6059-4f95-a2cd-cbbbee7ed329]
+tempest.api.image.v2.test_images_tags_negative.ImagesTagsNegativeTest.test_delete_non_existing_tag[id-39c023a2-325a-433a-9eea-649bf1414b19]
+tempest.api.image.v2.test_images_tags_negative.ImagesTagsNegativeTest.test_update_tags_for_non_existing_image[id-8cd30f82-6f9a-4c6e-8034-c1b51fba43d9]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcp_stateful[id-4ab211a0-276f-4552-9070-51e27f58fecf]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcp_stateful_fixedips[id-51a5e97f-f02e-4e4e-9a17-a69811d300e3]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcp_stateful_fixedips_duplicate[id-57b8302b-cba9-4fbb-8835-9168df029051]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcp_stateful_fixedips_outrange[id-98244d88-d990-4570-91d4-6b25d70d08af]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcp_stateful_router[id-e98f65db-68f4-4330-9fea-abd8c5192d4d]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_64_subnets[id-4256c61d-c538-41ea-9147-3c450c36669e]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_invalid_options[id-81f18ef6-95b5-4584-9966-10d480b7496a]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_stateless_eui64[id-e5517e62-6f16-430d-a672-f80875493d4c]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_stateless_no_ra[id-ae2f4a5d-03ff-4c42-a3b0-ce2fcb7ea832]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_stateless_no_ra_no_dhcp[id-21635b6f-165a-4d42-bf49-7d195e47342f]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_two_subnets[id-4544adf7-bb5f-4bdc-b769-b3e77026cef2]
+tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_create_floating_ip_specifying_a_fixed_ip_address[id-36de4bd0-f09c-43e3-a8e1-1decc1ffd3a5]
+tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_create_update_floatingip_with_port_multiple_ip_address[id-45c4c683-ea97-41ef-9c51-5e9802f2f3d7]
+tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_floating_ip_delete_port[id-e1f6bffd-442f-4668-b30e-df13f2705e77]
+tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_floating_ip_update_different_router[id-1bb2f731-fe5a-4b8c-8409-799ade1bed4d]
+tempest.api.network.test_floating_ips_negative.FloatingIPNegativeTestJSON.test_associate_floatingip_port_ext_net_unreachable[id-6b3b8797-6d43-4191-985c-c48b773eb429]
+tempest.api.network.test_floating_ips_negative.FloatingIPNegativeTestJSON.test_create_floatingip_in_private_network[id-50b9aeb4-9f0b-48ee-aa31-fa955a48ff54]
+tempest.api.network.test_floating_ips_negative.FloatingIPNegativeTestJSON.test_create_floatingip_with_port_ext_net_unreachable[id-22996ea8-4a81-4b27-b6e1-fa5df92fa5e8]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_all_attributes[id-a4d9ec4c-0306-4111-a75c-db01a709030b]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_allocation_pools[id-bec949c4-3147-4ba6-af5f-cd2306118404]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_dhcp_enabled[id-94ce038d-ff0a-4a4c-a56b-09da3ca0b55d]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_gw[id-9393b468-186d-496d-aa36-732348cd76e7]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_gw_and_allocation_pools[id-8217a149-0c6c-4cfb-93db-0486f707d13f]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_host_routes_and_dns_nameservers[id-d830de0a-be47-468f-8f02-1fd996118289]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_without_gateway[id-d2d596e2-8e76-47a9-ac51-d4648009f4d3]
+tempest.api.network.test_networks.NetworksTest.test_create_update_delete_network_subnet[id-0e269138-0da6-4efc-a46d-578161e7b221]
+tempest.api.network.test_networks.NetworksTest.test_delete_network_with_subnet[id-f04f61a9-b7f3-4194-90b2-9bcf660d1bfe]
+tempest.api.network.test_networks.NetworksTest.test_external_network_visibility[id-af774677-42a9-4e4b-bb58-16fe6a5bc1ec]
+tempest.api.network.test_networks.NetworksTest.test_list_networks[id-f7ffdeda-e200-4a7a-bcbe-05716e86bf43]
+tempest.api.network.test_networks.NetworksTest.test_list_networks_fields[id-6ae6d24f-9194-4869-9c85-c313cb20e080]
+tempest.api.network.test_networks.NetworksTest.test_list_subnets[id-db68ba48-f4ea-49e9-81d1-e367f6d0b20a]
+tempest.api.network.test_networks.NetworksTest.test_list_subnets_fields[id-842589e3-9663-46b0-85e4-7f01273b0412]
+tempest.api.network.test_networks.NetworksTest.test_show_network[id-2bf13842-c93f-4a69-83ed-717d2ec3b44e]
+tempest.api.network.test_networks.NetworksTest.test_show_network_fields[id-867819bb-c4b6-45f7-acf9-90edcf70aa5e]
+tempest.api.network.test_networks.NetworksTest.test_show_subnet[id-bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc]
+tempest.api.network.test_networks.NetworksTest.test_show_subnet_fields[id-270fff0b-8bfc-411f-a184-1e8fd35286f0]
+tempest.api.network.test_networks.NetworksTest.test_update_subnet_gw_dns_host_routes_dhcp[id-3d3852eb-3009-49ec-97ac-5ce83b73010a]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_all_attributes[id-a4d9ec4c-0306-4111-a75c-db01a709030b]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_allocation_pools[id-bec949c4-3147-4ba6-af5f-cd2306118404]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_dhcp_enabled[id-94ce038d-ff0a-4a4c-a56b-09da3ca0b55d]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_gw[id-9393b468-186d-496d-aa36-732348cd76e7]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_gw_and_allocation_pools[id-8217a149-0c6c-4cfb-93db-0486f707d13f]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_host_routes_and_dns_nameservers[id-d830de0a-be47-468f-8f02-1fd996118289]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_without_gateway[id-d2d596e2-8e76-47a9-ac51-d4648009f4d3]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_update_delete_network_subnet[id-0e269138-0da6-4efc-a46d-578161e7b221]
+tempest.api.network.test_networks.NetworksTestJSON.test_delete_network_with_subnet[id-f04f61a9-b7f3-4194-90b2-9bcf660d1bfe]
+tempest.api.network.test_networks.NetworksTestJSON.test_external_network_visibility[id-af774677-42a9-4e4b-bb58-16fe6a5bc1ec]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_networks[id-f7ffdeda-e200-4a7a-bcbe-05716e86bf43]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_networks_fields[id-6ae6d24f-9194-4869-9c85-c313cb20e080]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_subnets[id-db68ba48-f4ea-49e9-81d1-e367f6d0b20a]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_subnets_fields[id-842589e3-9663-46b0-85e4-7f01273b0412]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_network[id-2bf13842-c93f-4a69-83ed-717d2ec3b44e]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_network_fields[id-867819bb-c4b6-45f7-acf9-90edcf70aa5e]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_subnet[id-bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_subnet_fields[id-270fff0b-8bfc-411f-a184-1e8fd35286f0]
+tempest.api.network.test_networks.NetworksTestJSON.test_update_subnet_gw_dns_host_routes_dhcp[id-3d3852eb-3009-49ec-97ac-5ce83b73010a]
+tempest.api.network.test_ports.PortsTestJSON.test_create_bulk_port[id-67f1b811-f8db-43e2-86bd-72c074d4a42c]
+tempest.api.network.test_ports.PortsTestJSON.test_create_port_in_allowed_allocation_pools[id-0435f278-40ae-48cb-a404-b8a087bc09b1]
+tempest.api.network.test_ports.PortsTestJSON.test_create_update_delete_port[id-c72c1c0c-2193-4aca-aaa4-b1442640f51c]
+tempest.api.network.test_ports.PortsTestJSON.test_list_ports[id-cf95b358-3e92-4a29-a148-52445e1ac50e]
+tempest.api.network.test_ports.PortsTestJSON.test_list_ports_fields[id-ff7f117f-f034-4e0e-abff-ccef05c454b4]
+tempest.api.network.test_ports.PortsTestJSON.test_port_list_filter_by_router_id[id-5ad01ed0-0e6e-4c5d-8194-232801b15c72]
+tempest.api.network.test_ports.PortsTestJSON.test_show_port[id-c9a685bd-e83f-499c-939f-9f7863ca259f]
+tempest.api.network.test_ports.PortsTestJSON.test_show_port_fields[id-45fcdaf2-dab0-4c13-ac6c-fcddfb579dbd]
+tempest.api.network.test_routers.RoutersTest.test_add_multiple_router_interfaces[id-802c73c9-c937-4cef-824b-2191e24a6aab]
+tempest.api.network.test_routers.RoutersTest.test_add_remove_router_interface_with_port_id[id-2b7d2f37-6748-4d78-92e5-1d590234f0d5]
+tempest.api.network.test_routers.RoutersTest.test_add_remove_router_interface_with_subnet_id[id-b42e6e39-2e37-49cc-a6f4-8467e940900a]
+tempest.api.network.test_routers.RoutersTest.test_create_show_list_update_delete_router[id-f64403e2-8483-4b34-8ccd-b09a87bcc68c]
+tempest.api.network.test_routers.RoutersTest.test_router_interface_port_update_with_fixed_ip[id-96522edf-b4b5-45d9-8443-fa11c26e6eff]
+tempest.api.network.test_routers.RoutersTest.test_update_delete_extra_route[id-c86ac3a8-50bd-4b00-a6b8-62af84a0765c]
+tempest.api.network.test_routers.RoutersTest.test_update_extra_route[id-c86ac3a8-50bd-4b00-a6b8-62af84a0765c]
+tempest.api.network.test_routers.RoutersTest.test_update_router_admin_state[id-a8902683-c788-4246-95c7-ad9c6d63a4d9]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_add_router_interfaces_on_overlapping_subnets_returns_400[id-957751a3-3c68-4fa2-93b6-eb52ea10db6e]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_delete_non_existent_router_returns_404[id-c7edc5ad-d09d-41e6-a344-5c0c31e2e3e4]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_router_add_gateway_invalid_network_returns_404[id-37a94fc0-a834-45b9-bd23-9a81d2fd1e22]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_router_add_gateway_net_not_external_returns_400[id-11836a18-0b15-4327-a50b-f0d9dc66bddd]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_router_remove_interface_in_use_returns_409[id-04df80f9-224d-47f5-837a-bf23e33d1c20]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_show_non_existent_router_returns_404[id-c2a70d72-8826-43a7-8208-0209e6360c47]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_update_non_existent_router_returns_404[id-b23d1569-8b0c-4169-8d4b-6abd34fad5c7]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_list_update_show_delete_security_group[id-bfd128e5-3c92-44b6-9d66-7fe29d22c802]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_additional_args[id-87dfbcf9-1849-43ea-b1e4-efa3eeae9f71]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_icmp_type_code[id-c9463db8-b44d-4f52-b6c0-8dbda99f26ce]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_protocol_integer_value[id-0a307599-6655-4220-bebc-fd70c64f2290]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_remote_group_id[id-c2ed2deb-7a0c-44d8-8b4c-a5825b5c310b]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_remote_ip_prefix[id-16459776-5da2-4634-bce4-4b55ee3ec188]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_show_delete_security_group_rule[id-cfb99e0e-7410-4a3d-8a0c-959a63ee77e9]
+tempest.api.network.test_security_groups.SecGroupTest.test_list_security_groups[id-e30abd17-fef9-4739-8617-dc26da88e686]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_additional_default_security_group_fails[id-2323061e-9fbf-4eb0-b547-7e8fafc90849]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_duplicate_security_group_rule_fails[id-8fde898f-ce88-493b-adc9-4e4692879fc5]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_ethertype[id-5666968c-fff3-40d6-9efc-df1c8bd01abb]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_protocol[id-981bdc22-ce48-41ed-900a-73148b583958]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_remote_ip_prefix[id-5f8daf69-3c5f-4aaa-88c9-db1d66f68679]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_invalid_ports[id-0d9c7791-f2ad-4e2f-ac73-abf2373b0d2d]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_non_existent_remote_groupid[id-4bf786fd-2f02-443c-9716-5b98e159a49a]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_non_existent_security_group[id-be308db6-a7cf-4d5c-9baf-71bafd73f35e]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_delete_non_existent_security_group[id-1f1bb89d-5664-4956-9fcd-83ee0fa603df]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_show_non_existent_security_group[id-424fd5c3-9ddc-486a-b45f-39bf0c820fc6]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_show_non_existent_security_group_rule[id-4c094c09-000b-4e41-8100-9617600c02a6]
+tempest.api.network.test_subnetpools_extensions.SubnetPoolsTestJSON.test_create_list_show_update_delete_subnetpools[id-62595970-ab1c-4b7f-8fcc-fddfe55e9811]
+tempest.api.network.test_versions.NetworksApiDiscovery.test_api_version_resources[id-cac8a836-c2e0-4304-b556-cd299c7281d1]
+tempest.api.volume.test_availability_zone.AvailabilityZoneTestJSON.test_get_availability_zone_list[id-01f1ae88-eba9-4c6b-a011-6f7ace06b725]
+tempest.api.volume.test_availability_zone.AvailabilityZoneV2TestJSON.test_get_availability_zone_list[id-01f1ae88-eba9-4c6b-a011-6f7ace06b725]
+tempest.api.volume.test_extensions.ExtensionsTestJSON.test_list_extensions[id-94607eb0-43a5-47ca-82aa-736b41bd2e2c]
+tempest.api.volume.test_extensions.ExtensionsV2TestJSON.test_list_extensions[id-94607eb0-43a5-47ca-82aa-736b41bd2e2c]
+tempest.api.volume.test_snapshot_metadata.SnapshotMetadataTestJSON.test_crud_snapshot_metadata[id-a2f20f99-e363-4584-be97-bc33afb1a56c]
+tempest.api.volume.test_snapshot_metadata.SnapshotMetadataTestJSON.test_update_show_snapshot_metadata_item[id-e8ff85c5-8f97-477f-806a-3ac364a949ed]
+tempest.api.volume.test_snapshot_metadata.SnapshotMetadataTestJSON.test_update_snapshot_metadata_item[id-e8ff85c5-8f97-477f-806a-3ac364a949ed]
+tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_create_get_delete_snapshot_metadata[id-a2f20f99-e363-4584-be97-bc33afb1a56c]
+tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_crud_snapshot_metadata[id-a2f20f99-e363-4584-be97-bc33afb1a56c]
+tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_update_snapshot_metadata_item[id-e8ff85c5-8f97-477f-806a-3ac364a949ed]
+tempest.api.volume.test_versions.VersionsTest.test_list_versions[id-77838fc4-b49b-4c64-9533-166762517369]
+tempest.api.volume.test_volume_metadata.VolumesMetadataTest.test_create_get_delete_volume_metadata[id-6f5b125b-f664-44bf-910f-751591fe5769]
+tempest.api.volume.test_volume_metadata.VolumesMetadataTest.test_crud_volume_metadata[id-6f5b125b-f664-44bf-910f-751591fe5769]
+tempest.api.volume.test_volume_metadata.VolumesMetadataTest.test_update_show_volume_metadata_item[id-862261c5-8df4-475a-8c21-946e50e36a20]
+tempest.api.volume.test_volume_metadata.VolumesMetadataTest.test_update_volume_metadata_item[id-862261c5-8df4-475a-8c21-946e50e36a20]
+tempest.api.volume.test_volume_metadata.VolumesV2MetadataTest.test_create_get_delete_volume_metadata[id-6f5b125b-f664-44bf-910f-751591fe5769]
+tempest.api.volume.test_volume_metadata.VolumesV2MetadataTest.test_update_volume_metadata_item[id-862261c5-8df4-475a-8c21-946e50e36a20]
+tempest.api.volume.test_volumes_actions.VolumesActionsTest.test_volume_bootable[id-63e21b4c-0a0c-41f6-bfc3-7c2816815599]
+tempest.api.volume.test_volumes_actions.VolumesActionsTest.test_volume_readonly_update[id-fff74e1e-5bd3-4b33-9ea9-24c103bc3f59]
+tempest.api.volume.test_volumes_actions.VolumesActionsTest.test_volume_upload[id-d8f1ca95-3d5b-44a3-b8ca-909691c9532d]
+tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_volume_bootable[id-63e21b4c-0a0c-41f6-bfc3-7c2816815599]
+tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_volume_readonly_update[id-fff74e1e-5bd3-4b33-9ea9-24c103bc3f59]
+tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_volume_upload[id-d8f1ca95-3d5b-44a3-b8ca-909691c9532d]
+tempest.api.volume.test_volumes_get.VolumesGetTest.test_volume_create_get_update_delete[id-27fb0e9f-fb64-41dd-8bdb-1ffa762f0d51]
+tempest.api.volume.test_volumes_get.VolumesGetTest.test_volume_create_get_update_delete_as_clone[id-3f591b4a-7dc6-444c-bd51-77469506b3a1]
+tempest.api.volume.test_volumes_get.VolumesGetTest.test_volume_create_get_update_delete_from_image[id-54a01030-c7fc-447c-86ee-c1182beae638]
+tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete[id-27fb0e9f-fb64-41dd-8bdb-1ffa762f0d51]
+tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete_as_clone[id-3f591b4a-7dc6-444c-bd51-77469506b3a1]
+tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete_from_image[id-54a01030-c7fc-447c-86ee-c1182beae638]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list[id-0b6ddd39-b948-471f-8038-4787978747c4]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_by_name[id-a28e8da4-0b56-472f-87a8-0f4d3f819c02]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_details_by_name[id-2de3a6d4-12aa-403b-a8f2-fdeb42a89623]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_details_pagination[id-e9138a2c-f67b-4796-8efa-635c196d01de]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_details_with_multiple_params[id-2a7064eb-b9c3-429b-b888-33928fc5edd3]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_pagination[id-af55e775-8e4b-4feb-8719-215c43b0238c]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_param_display_name_and_status[id-777c87c1-2fc4-4883-8b8e-5c0b951d1ec8]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_with_detail_param_display_name_and_status[id-856ab8ca-6009-4c37-b691-be1065528ad4]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_with_detail_param_metadata[id-1ca92d3c-4a8e-4b43-93f5-e4c7fb3b291d]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_with_details[id-adcbb5a7-5ad8-4b61-bd10-5380e111a877]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_with_param_metadata[id-b5ebea1b-0603-40a0-bb41-15fcd0a53214]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volumes_list_by_availability_zone[id-c0cfa863-3020-40d7-b587-e35f597d5d87]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volumes_list_by_status[id-39654e13-734c-4dab-95ce-7613bf8407ce]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volumes_list_details_by_availability_zone[id-e1b80d13-94f0-4ba2-a40e-386af29f8db1]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volumes_list_details_by_status[id-2943f712-71ec-482a-bf49-d5ca06216b9f]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list[id-0b6ddd39-b948-471f-8038-4787978747c4]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_by_name[id-a28e8da4-0b56-472f-87a8-0f4d3f819c02]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_by_name[id-2de3a6d4-12aa-403b-a8f2-fdeb42a89623]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_param_display_name_and_status[id-777c87c1-2fc4-4883-8b8e-5c0b951d1ec8]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_detail_param_display_name_and_status[id-856ab8ca-6009-4c37-b691-be1065528ad4]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_detail_param_metadata[id-1ca92d3c-4a8e-4b43-93f5-e4c7fb3b291d]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_details[id-adcbb5a7-5ad8-4b61-bd10-5380e111a877]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_param_metadata[id-b5ebea1b-0603-40a0-bb41-15fcd0a53214]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_by_availability_zone[id-c0cfa863-3020-40d7-b587-e35f597d5d87]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_by_status[id-39654e13-734c-4dab-95ce-7613bf8407ce]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_details_by_availability_zone[id-e1b80d13-94f0-4ba2-a40e-386af29f8db1]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_details_by_status[id-2943f712-71ec-482a-bf49-d5ca06216b9f]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_invalid_size[id-1ed83a8a-682d-4dfb-a30e-ee63ffd6c049]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_nonexistent_snapshot_id[id-0c36f6ae-4604-4017-b0a9-34fdc63096f9]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_nonexistent_source_volid[id-47c73e08-4be8-45bb-bfdf-0c4e79b88344]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_nonexistent_volume_type[id-10254ed8-3849-454e-862e-3ab8e6aa01d2]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_size_negative[id-8b472729-9eba-446e-a83b-916bdb34bef7]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_size_zero[id-41331caa-eaf4-4001-869d-bc18c1869360]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_without_passing_size[id-9387686f-334f-4d31-a439-33494b9e2683]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_delete_invalid_volume_id[id-1f035827-7c32-4019-9240-b4ec2dbd9dfd]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_delete_volume_without_passing_volume_id[id-441a1550-5d44-4b30-af0f-a6d402f52026]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_get_invalid_volume_id[id-30799cfd-7ee4-446c-b66c-45b383ed211b]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_get_volume_without_passing_volume_id[id-c6c3db06-29ad-4e91-beb0-2ab195fe49e3]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_list_volumes_detail_with_invalid_status[id-ba94b27b-be3f-496c-a00e-0283b373fa75]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_list_volumes_detail_with_nonexistent_name[id-9ca17820-a0e7-4cbd-a7fa-f4468735e359]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_list_volumes_with_invalid_status[id-143b279b-7522-466b-81be-34a87d564a7c]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_list_volumes_with_nonexistent_name[id-0f4aa809-8c7b-418f-8fb3-84c7a5dfc52f]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_update_volume_with_empty_volume_id[id-72aeca85-57a5-4c1f-9057-f320f9ea575b]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_update_volume_with_invalid_volume_id[id-e66e40d6-65e6-4e75-bdc7-636792fa152d]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_update_volume_with_nonexistent_volume_id[id-0186422c-999a-480e-a026-6a665744c30c]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_volume_delete_nonexistent_volume_id[id-555efa6e-efcd-44ef-8a3b-4a7ca4837a29]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_volume_get_nonexistent_volume_id[id-f131c586-9448-44a4-a8b0-54ca838aa43e]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_invalid_size[id-1ed83a8a-682d-4dfb-a30e-ee63ffd6c049]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_snapshot_id[id-0c36f6ae-4604-4017-b0a9-34fdc63096f9]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_source_volid[id-47c73e08-4be8-45bb-bfdf-0c4e79b88344]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_volume_type[id-10254ed8-3849-454e-862e-3ab8e6aa01d2]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_out_passing_size[id-9387686f-334f-4d31-a439-33494b9e2683]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_size_negative[id-8b472729-9eba-446e-a83b-916bdb34bef7]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_size_zero[id-41331caa-eaf4-4001-869d-bc18c1869360]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_without_passing_size[id-9387686f-334f-4d31-a439-33494b9e2683]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_delete_invalid_volume_id[id-1f035827-7c32-4019-9240-b4ec2dbd9dfd]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_delete_volume_without_passing_volume_id[id-441a1550-5d44-4b30-af0f-a6d402f52026]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_get_invalid_volume_id[id-30799cfd-7ee4-446c-b66c-45b383ed211b]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_get_volume_without_passing_volume_id[id-c6c3db06-29ad-4e91-beb0-2ab195fe49e3]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_detail_with_invalid_status[id-ba94b27b-be3f-496c-a00e-0283b373fa75]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_detail_with_nonexistent_name[id-9ca17820-a0e7-4cbd-a7fa-f4468735e359]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_with_invalid_status[id-143b279b-7522-466b-81be-34a87d564a7c]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_with_nonexistent_name[id-0f4aa809-8c7b-418f-8fb3-84c7a5dfc52f]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_empty_volume_id[id-72aeca85-57a5-4c1f-9057-f320f9ea575b]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_invalid_volume_id[id-e66e40d6-65e6-4e75-bdc7-636792fa152d]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_nonexistent_volume_id[id-0186422c-999a-480e-a026-6a665744c30c]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_volume_delete_nonexistent_volume_id[id-555efa6e-efcd-44ef-8a3b-4a7ca4837a29]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_volume_get_nonexistent_volume_id[id-f131c586-9448-44a4-a8b0-54ca838aa43e]
+tempest.api.volume.test_volumes_snapshots.VolumesSnapshotTestJSON.test_snapshot_create_get_list_update_delete[id-2a8abbe4-d871-46db-b049-c41f5af8216e]
+tempest.api.volume.test_volumes_snapshots.VolumesSnapshotTestJSON.test_volume_from_snapshot[id-677863d1-3142-456d-b6ac-9924f667a7f4]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshot_create_get_list_update_delete[id-2a8abbe4-d871-46db-b049-c41f5af8216e]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshots_list_details_with_params[id-220a1022-1fcd-4a74-a7bd-6b859156cda2]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshots_list_with_params[id-59f41f43-aebf-48a9-ab5d-d76340fab32b]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_volume_from_snapshot[id-677863d1-3142-456d-b6ac-9924f667a7f4]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_limit[id-db4d8e0a-7a2e-41cc-a712-961f6844e896]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_limit_equals_infinite[id-a1427f61-420e-48a5-b6e3-0b394fa95400]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_limit_equals_zero[id-e3b44b7f-ae87-45b5-8a8c-66110eb24d0a]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_marker[id-05489dde-44bc-4961-a1f5-3ce7ee7824f7]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_offset[id-ca96d551-17c6-4e11-b0e8-52d3bb8a63c7]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_created_at_asc[id-4052c3a0-2415-440a-a8cc-305a875331b0]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_created_at_desc[id-dcbbe24a-f3c0-4ec8-9274-55d48db8d1cf]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_id_asc[id-c5513ada-64c1-4d28-83b9-af3307ec1388]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_id_desc[id-8a7fe058-0b41-402a-8afd-2dbc5a4a718b]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_name_asc[id-d58b5fed-0c37-42d3-8c5d-39014ac13c00]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_name_desc[id-96ba6f4d-1f18-47e1-b4bc-76edc6c21250]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshots_list_details_with_params[id-220a1022-1fcd-4a74-a7bd-6b859156cda2]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshots_list_with_params[id-59f41f43-aebf-48a9-ab5d-d76340fab32b]
+tempest.api.volume.test_volumes_snapshots_list.VolumesV2SnapshotListTestJSON.test_snapshots_list_details_with_params[id-220a1022-1fcd-4a74-a7bd-6b859156cda2]
+tempest.api.volume.test_volumes_snapshots_list.VolumesV2SnapshotListTestJSON.test_snapshots_list_with_params[id-59f41f43-aebf-48a9-ab5d-d76340fab32b]
+tempest.api.volume.test_volumes_snapshots_negative.VolumesSnapshotNegativeTestJSON.test_create_snapshot_with_nonexistent_volume_id[id-e3e466af-70ab-4f4b-a967-ab04e3532ea7]
+tempest.api.volume.test_volumes_snapshots_negative.VolumesSnapshotNegativeTestJSON.test_create_snapshot_without_passing_volume_id[id-bb9da53e-d335-4309-9c15-7e76fd5e4d6d]
+tempest.api.volume.test_volumes_snapshots_negative.VolumesV2SnapshotNegativeTestJSON.test_create_snapshot_with_nonexistent_volume_id[id-e3e466af-70ab-4f4b-a967-ab04e3532ea7]
+tempest.api.volume.test_volumes_snapshots_negative.VolumesV2SnapshotNegativeTestJSON.test_create_snapshot_without_passing_volume_id[id-bb9da53e-d335-4309-9c15-7e76fd5e4d6d]
+tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_pagination[id-e9138a2c-f67b-4796-8efa-635c196d01de]
+tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_with_multiple_params[id-2a7064eb-b9c3-429b-b888-33928fc5edd3]
+tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_pagination[id-af55e775-8e4b-4feb-8719-215c43b0238c]
diff --git a/docker/smoke/hooks/post_checkout b/docker/smoke/hooks/post_checkout
index 3e5670b4a..b23f6f449 100644
--- a/docker/smoke/hooks/post_checkout
+++ b/docker/smoke/hooks/post_checkout
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
from="${DOCKER_REPO%/*}/functest-tempest:${DOCKER_TAG}"
sed -i "s|^FROM.*$|FROM ${from}|" Dockerfile
diff --git a/docker/smoke/object.txt b/docker/smoke/object.txt
new file mode 100644
index 000000000..720532e2a
--- /dev/null
+++ b/docker/smoke/object.txt
@@ -0,0 +1,66 @@
+tempest.api.identity.v3.test_tokens.TokensV3Test.test_create_token[id-6f8e4436-fc96-4282-8122-e41df57197a9]
+tempest.api.identity.v3.test_tokens.TokensV3Test.test_token_auth_creation_existence_deletion[id-0f9f5a5f-d5cd-4a86-8a5b-c5ded151f212]
+tempest.api.object_storage.test_account_bulk.BulkTest.test_bulk_delete[id-c075e682-0d2a-43b2-808d-4116200d736d]
+tempest.api.object_storage.test_account_bulk.BulkTest.test_extract_archive[id-a407de51-1983-47cc-9f14-47c2b059413c]
+tempest.api.object_storage.test_account_quotas.AccountQuotasTest.test_upload_valid_object[id-a22ef352-a342-4587-8f47-3bbdb5b039c4]
+tempest.api.object_storage.test_account_quotas_negative.AccountQuotasNegativeTest.test_user_modify_quota[id-d1dc5076-555e-4e6d-9697-28f1fe976324]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers[id-3499406a-ae53-4f8c-b43a-133d4dc6fe3f]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_end_marker[id-5ca164e4-7bde-43fa-bafb-913b53b9e786]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_format_json[id-1c7efa35-e8a2-4b0b-b5ff-862c7fd83704]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_limit[id-5cfa4ab2-4373-48dd-a41f-a532b12b08b2]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_limit_and_end_marker[id-888a3f0e-7214-4806-8e50-5e0c9a69bb5e]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_limit_and_marker[id-f7064ae8-dbcc-48da-b594-82feef6ea5af]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_limit_and_marker_and_end_marker[id-8cf98d9c-e3a0-4e44-971b-c87656fdddbd]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_marker[id-638f876d-6a43-482a-bbb3-0840bca101c6]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_marker_and_end_marker[id-ac8502c2-d4e4-4f68-85a6-40befea2ef5e]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_extensions[id-6eb04a6a-4860-4e31-ba91-ea3347d76b58]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_extensions[id-6eb04a6a-4860-4e31-ba91-ea3347d76b58]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_no_account_metadata[id-b904c2e3-24c2-4dba-ad7d-04e90a761be5]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_no_containers[id-884ec421-fbad-4fcc-916b-0580f2699565]
+tempest.api.object_storage.test_account_services.AccountTest.test_update_account_metadata_with_create_metadata_key[id-64fd53f3-adbd-4639-af54-436e4982dbfb]
+tempest.api.object_storage.test_account_services.AccountTest.test_update_account_metadata_with_delete_metadata[id-9f60348d-c46f-4465-ae06-d51dbd470953]
+tempest.api.object_storage.test_account_services.AccountTest.test_update_account_metadata_with_delete_metadata_key[id-d4d884d3-4696-4b85-bc98-4f57c4dd2bf1]
+tempest.api.object_storage.test_container_acl.ObjectTestACLs.test_read_object_with_rights[id-a3270f3f-7640-4944-8448-c7ea783ea5b6]
+tempest.api.object_storage.test_container_acl.ObjectTestACLs.test_write_object_with_rights[id-aa58bfa5-40d9-4bc3-82b4-d07f4a9e392a]
+tempest.api.object_storage.test_container_quotas.ContainerQuotasTest.test_upload_large_object[id-22eeeb2b-3668-4160-baef-44790f65a5a0]
+tempest.api.object_storage.test_container_quotas.ContainerQuotasTest.test_upload_too_many_objects[id-3a387039-697a-44fc-a9c0-935de31f426b]
+tempest.api.object_storage.test_container_quotas.ContainerQuotasTest.test_upload_valid_object[id-9a0fb034-86af-4df0-86fa-f8bd7db21ae0]
+tempest.api.object_storage.test_container_services.ContainerTest.test_create_container[id-92139d73-7819-4db1-85f8-3f2f22a8d91f]
+tempest.api.object_storage.test_container_services.ContainerTest.test_create_container_overwrite[id-49f866ed-d6af-4395-93e7-4187eb56d322]
+tempest.api.object_storage.test_container_services.ContainerTest.test_delete_container[id-95d3a249-b702-4082-a2c4-14bb860cf06a]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents[id-312ff6bd-5290-497f-bda1-7c5fec6697ab]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_delimiter[id-fe323a32-57b9-4704-a996-2e68f83b09bc]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_end_marker[id-55b4fa5c-e12e-4ca9-8fcf-a79afe118522]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_format_json[id-196f5034-6ab0-4032-9da9-a937bbb9fba9]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_limit[id-297ec38b-2b61-4ff4-bcd1-7fa055e97b61]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_marker[id-c31ddc63-2a58-4f6b-b25c-94d2937e6867]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_no_object[id-4646ac2d-9bfb-4c7d-a3c5-0f527402b3df]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_path[id-58ca6cc9-6af0-408d-aaec-2a6a7b2f0df9]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_prefix[id-77e742c7-caf2-4ec9-8aa4-f7d509a3344c]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_metadata[id-96e68f0e-19ec-4aa2-86f3-adc6a45e14dd]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_no_container_metadata[id-a2faf936-6b13-4f8d-92a2-c2278355821e]
+tempest.api.object_storage.test_container_services.ContainerTest.test_update_container_metadata_with_create_and_delete_metadata[id-cf19bc0b-7e16-4a5a-aaed-cb0c2fe8deef]
+tempest.api.object_storage.test_container_services.ContainerTest.test_update_container_metadata_with_create_metadata[id-2ae5f295-4bf1-4e04-bfad-21e54b62cec5]
+tempest.api.object_storage.test_container_services.ContainerTest.test_update_container_metadata_with_create_metadata_key[id-31f40a5f-6a52-4314-8794-cd89baed3040]
+tempest.api.object_storage.test_container_services.ContainerTest.test_update_container_metadata_with_delete_metadata[id-3a5ce7d4-6e4b-47d0-9d87-7cd42c325094]
+tempest.api.object_storage.test_container_services.ContainerTest.test_update_container_metadata_with_delete_metadata_key[id-a2e36378-6f1f-43f4-840a-ffd9cfd61914]
+tempest.api.object_storage.test_object_expiry.ObjectExpiryTest.test_get_object_after_expiry_time[id-fb024a42-37f3-4ba5-9684-4f40a7910b41]
+tempest.api.object_storage.test_object_services.ObjectTest.test_copy_object_2d_way[id-06f90388-2d0e-40aa-934c-e9a8833e958a]
+tempest.api.object_storage.test_object_services.ObjectTest.test_copy_object_across_containers[id-aa467252-44f3-472a-b5ae-5b57c3c9c147]
+tempest.api.object_storage.test_object_services.ObjectTest.test_copy_object_in_same_container[id-1a9ab572-1b66-4981-8c21-416e2a5e6011]
+tempest.api.object_storage.test_object_services.ObjectTest.test_copy_object_to_itself[id-2248abba-415d-410b-9c30-22dff9cd6e67]
+tempest.api.object_storage.test_object_services.ObjectTest.test_create_object[id-5b4ce26f-3545-46c9-a2ba-5754358a4c62]
+tempest.api.object_storage.test_object_services.ObjectTest.test_delete_object[id-17738d45-03bd-4d45-9e0b-7b2f58f98687]
+tempest.api.object_storage.test_object_services.ObjectTest.test_get_object[id-02610ba7-86b7-4272-9ed8-aa8d417cb3cd]
+tempest.api.object_storage.test_object_services.ObjectTest.test_get_object_if_different[id-50d01f12-526f-4360-9ac2-75dd508d7b68]
+tempest.api.object_storage.test_object_services.ObjectTest.test_get_object_with_x_object_manifest[id-e3e6a64a-9f50-4955-b987-6ce6767c97fb]
+tempest.api.object_storage.test_object_services.ObjectTest.test_list_object_metadata_with_x_object_manifest[id-23a3674c-d6de-46c3-86af-ff92bfc8a3da]
+tempest.api.object_storage.test_object_services.ObjectTest.test_object_upload_in_segments[id-e3e6a64a-9f50-4955-b987-6ce6767c97fb]
+tempest.api.object_storage.test_object_services.ObjectTest.test_object_upload_in_segments[id-e3e6a64a-9f50-4955-b987-6ce6767c97fb]
+tempest.api.object_storage.test_object_slo.ObjectSloTest.test_delete_large_object[id-87b6dfa1-abe9-404d-8bf0-6c3751e6aa77]
+tempest.api.object_storage.test_object_slo.ObjectSloTest.test_list_large_object_metadata[id-e69ad766-e1aa-44a2-bdd2-bf62c09c1456]
+tempest.api.object_storage.test_object_slo.ObjectSloTest.test_retrieve_large_object[id-49bc49bc-dd1b-4c0f-904e-d9f10b830ee8]
+tempest.api.object_storage.test_object_slo.ObjectSloTest.test_upload_manifest[id-2c3f24a6-36e8-4711-9aa2-800ee1fc7b5b]
+tempest.api.object_storage.test_object_temp_url.ObjectTempUrlTest.test_get_object_using_temp_url[id-f91c96d4-1230-4bba-8eb9-84476d18d991]
+tempest.api.object_storage.test_object_temp_url.ObjectTempUrlTest.test_put_object_using_temp_url[id-9b08dade-3571-4152-8a4f-a4f2a873a735]
+tempest.api.object_storage.test_object_version.ContainerTest.test_versioned_container[id-a151e158-dcbf-4a1f-a1e7-46cd65895a6f]
diff --git a/docker/smoke/platform.txt b/docker/smoke/platform.txt
new file mode 100644
index 000000000..4eca58790
--- /dev/null
+++ b/docker/smoke/platform.txt
@@ -0,0 +1,432 @@
+tempest.api.compute.flavors.test_flavors.FlavorsV2TestJSON.test_list_flavors[id-e36c0eaa-dff5-4082-ad1f-3f9a80aa3f59]
+tempest.api.compute.flavors.test_flavors.FlavorsV2TestJSON.test_list_flavors_with_detail[id-6e85fde4-b3cd-4137-ab72-ed5f418e8c24]
+tempest.api.compute.images.test_images_oneserver.ImagesOneServerTestJSON.test_create_delete_image[id-3731d080-d4c5-4872-b41a-64d0d0021314]
+tempest.api.compute.images.test_images_oneserver.ImagesOneServerTestJSON.test_create_image_specify_multibyte_character_image_name[id-3b7c6fe4-dfe7-477c-9243-b06359db51e6]
+tempest.api.compute.keypairs.test_keypairs_v22.KeyPairsV22TestJSON.test_keypairsv22_create_list_show_with_type[id-89d59d43-f735-441a-abcf-0601727f47b6]
+tempest.api.compute.security_groups.test_security_groups.SecurityGroupsTestJSON.test_list_security_groups_by_server[id-79517d60-535a-438f-af3d-e6feab1cbea7]
+tempest.api.compute.security_groups.test_security_groups.SecurityGroupsTestJSON.test_security_group_create_get_delete[id-ecc0da4a-2117-48af-91af-993cca39a615]
+tempest.api.compute.security_groups.test_security_groups.SecurityGroupsTestJSON.test_security_groups_create_list_delete[id-eb2b087d-633d-4d0d-a7bd-9e6ba35b32de]
+tempest.api.compute.security_groups.test_security_groups.SecurityGroupsTestJSON.test_server_security_groups[id-fe4abc0d-83f5-4c50-ad11-57a1127297a2]
+tempest.api.compute.security_groups.test_security_groups.SecurityGroupsTestJSON.test_update_security_groups[id-7d4e1d3c-3209-4d6d-b020-986304ebad1f]
+tempest.api.compute.security_groups.test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_delete_nonexistent_security_group[id-6727c00b-214c-4f9e-9a52-017ac3e98411]
+tempest.api.compute.security_groups.test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_delete_security_group_without_passing_id[id-1438f330-8fa4-4aeb-8a94-37c250106d7f]
+tempest.api.compute.security_groups.test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_delete_the_default_security_group[id-36a1629f-c6da-4a26-b8b8-55e7e5d5cd58]
+tempest.api.compute.security_groups.test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_security_group_get_nonexistent_group[id-673eaec1-9b3e-48ed-bdf1-2786c1b9661c]
+tempest.api.compute.security_groups.test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_update_non_existent_security_group[id-27edee9c-873d-4da6-a68a-3c256efebe8f]
+tempest.api.compute.servers.test_availability_zone.AZV2TestJSON.test_get_availability_zone_list_with_non_admin_user[id-a8333aa2-205c-449f-a828-d38c2489bf25]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_host_name_is_same_as_server_name[id-ac1ad47f-984b-4441-9274-c9079b7a0666]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_list_servers[id-9a438d88-10c6-4bcd-8b5b-5b6e25e1346f]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_list_servers_with_detail[id-585e934c-448e-43c4-acbf-d06a9b899997]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_verify_created_server_vcpus[id-cbc0f52f-05aa-492b-bdc1-84b575ca294b]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_verify_server_details[id-5de47127-9977-400a-936f-abcfbec1218f]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_host_name_is_same_as_server_name[id-ac1ad47f-984b-4441-9274-c9079b7a0666]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers[id-9a438d88-10c6-4bcd-8b5b-5b6e25e1346f]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers_with_detail[id-585e934c-448e-43c4-acbf-d06a9b899997]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_created_server_vcpus[id-cbc0f52f-05aa-492b-bdc1-84b575ca294b]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_server_details[id-5de47127-9977-400a-936f-abcfbec1218f]
+tempest.api.compute.servers.test_delete_server.DeleteServersTestJSON.test_delete_active_server[id-925fdfb4-5b13-47ea-ac8a-c36ae6fddb05]
+tempest.api.compute.servers.test_instance_actions.InstanceActionsTestJSON.test_get_instance_action[id-aacc71ca-1d70-4aa5-bbf6-0ff71470e43c]
+tempest.api.compute.servers.test_instance_actions.InstanceActionsTestJSON.test_list_instance_actions[id-77ca5cc5-9990-45e0-ab98-1de8fead201a]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_flavor[id-80c574cc-0925-44ba-8602-299028357dd9]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_image[id-b3304c3b-97df-46d2-8cd3-e2b6659724e7]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_server_name[id-f9eb2b70-735f-416c-b260-9914ac6181e4]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_server_status[id-de2612ab-b7dd-4044-b0b1-d2539601911f]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_limit_results[id-67aec2d0-35fe-4503-9f92-f13272b867ed]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_active_status[id-ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_flavor[id-573637f5-7325-47bb-9144-3476d0416908]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_image[id-05e8a8e7-9659-459a-989d-92c2f501f4ba]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_limit[id-614cdfc1-d557-4bac-915b-3e67b48eee76]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_server_name[id-9b067a7b-7fee-4f6a-b29c-be43fe18fc5a]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_server_status[id-ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filtered_by_ip_regex[id-a905e287-c35e-42f2-b132-d02b09f3654a]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filtered_by_name_wildcard[id-e9f624ee-92af-4562-8bec-437945a18dcb]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_changes_since_future_date[id-74745ad8-b346-45b5-b9b8-509d7447fc1f]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_changes_since_invalid_date[id-87d12517-e20a-4c9c-97b6-dd1628d6d6c9]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_greater_than_actual_count[id-d47c17fb-eebd-4287-8e95-f20a7e627b18]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_pass_negative_value[id-62610dd9-4713-4ee0-8beb-fd2c1aa7f950]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_pass_string[id-679bc053-5e70-4514-9800-3dfab1a380a6]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_flavor[id-5913660b-223b-44d4-a651-a0fbfd44ca75]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_image[id-ff01387d-c7ad-47b4-ae9e-64fa214638fe]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_server_name[id-e2c77c4a-000a-4af3-a0bd-629a328bde7c]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_detail_server_is_deleted[id-93055106-2d34-46fe-af68-d9ddbf7ee570]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_status_non_existing[id-fcdf192d-0f74-4d89-911f-1ec002b822c4]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_with_a_deleted_server[id-24a26f1a-1ddc-4eea-b0d7-a90cc874ad8f]
+tempest.api.compute.servers.test_multiple_create.MultipleCreateTestJSON.test_multiple_create[id-61e03386-89c3-449c-9bb1-a06f423fd9d1]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_lock_unlock_server[id-80a8094c-211e-440a-ab88-9e59d556c7ee]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_hard[id-2cb1baf6-ac8d-4429-bf0d-ba8a0ba53e32]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_rebuild_server[id-aaa6cdf3-55a7-461a-add9-1c8596b9a07c]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_stop_start_server[id-af8eafd4-38a7-4a4b-bdbc-75145a580560]
+tempest.api.compute.servers.test_server_tags.ServerTagsTestJSON.test_check_tag_existence[id-81279a66-61c3-4759-b830-a2dbe64cbe08]
+tempest.api.compute.servers.test_server_tags.ServerTagsTestJSON.test_create_delete_tag[id-8d95abe2-c658-4c42-9a44-c0258500306b]
+tempest.api.compute.servers.test_server_tags.ServerTagsTestJSON.test_delete_all_tags[id-a63b2a74-e918-4b7c-bcab-10c855f3a57e]
+tempest.api.compute.servers.test_server_tags.ServerTagsTestJSON.test_update_all_tags[id-a2c1af8c-127d-417d-974b-8115f7e3d831]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_server_with_admin_password[id-b92d5ec7-b1dd-44a2-87e4-45e888c46ef0]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_specify_keypair[id-f9e15296-d7f9-4e62-b53f-a04e89160833]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_with_existing_server_name[id-8fea6be7-065e-47cf-89b8-496e6f96c699]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_update_access_server_address[id-89b90870-bc13-4b73-96af-f9d4f2b70077]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_update_server_name[id-5e6ccff8-349d-4852-a8b3-055df7988dd2]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_numeric_server_name[id-fd57f159-68d6-4c2a-902b-03070828a87e]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_server_metadata_exceeds_length_limit[id-7fc74810-0bd2-4cd7-8244-4f33a9db865a]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_server_name_length_exceeds_256[id-c3e0fb12-07fc-4d76-a22e-37409887afe8]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_flavor[id-18f5227f-d155-4429-807c-ccb103887537]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_image[id-fcba1052-0a50-4cf3-b1ac-fae241edf02f]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_network_uuid[id-4e72dc2d-44c5-4336-9667-f7972e95c402]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_delete_server_pass_id_exceeding_length_limit[id-f4d7279b-5fd2-4bf2-9ba4-ae35df0d18c5]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_delete_server_pass_negative_id[id-75f79124-277c-45e6-a373-a1d6803f4cc4]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_get_non_existent_server[id-3436b02f-1b1e-4f03-881e-c6a602327439]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_invalid_ip_v6_address[id-5226dd80-1e9c-4d8a-b5f9-b26ca4763fd0]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server[id-d4c023a0-9c55-4747-9dd5-413b820143c7]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_deleted_server[id-98fa0458-1485-440f-873b-fe7f0d714930]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_non_existent_server[id-d86141a7-906e-4731-b187-d64a2ea61422]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_reboot_deleted_server[id-98fa0458-1485-440f-873b-fe7f0d714930]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_server_name_blank[id-dbbfd247-c40c-449e-8f6c-d2aa7c7da7cf]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_stop_non_existent_server[id-a31460a9-49e1-42aa-82ee-06e0bb7c2d03]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_name_of_non_existent_server[id-aa8eed43-e2cb-4ebf-930b-da14f6a21d81]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_server_name_length_exceeds_256[id-5c8e244c-dada-4590-9944-749c455b431f]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_server_set_empty_name[id-38204696-17c6-44da-9590-40f87fb5a899]
+tempest.api.compute.test_quotas.QuotasTestJSON.test_get_default_quotas[id-9bfecac7-b966-4f47-913f-1a9e2c12134a]
+tempest.api.compute.test_quotas.QuotasTestJSON.test_get_quotas[id-f1ef0a97-dbbb-4cca-adc5-c9fbc4f76107]
+tempest.api.compute.test_versions.TestVersions.test_list_api_versions[id-6c0a0990-43b6-4529-9b61-5fd8daf7c55c]
+tempest.api.compute.volumes.test_attach_volume.AttachVolumeTestJSON.test_attach_detach_volume[id-52e9045a-e90d-4c0d-9087-79d657faffff]
+tempest.api.compute.volumes.test_attach_volume.AttachVolumeTestJSON.test_list_get_volume_attachments[id-7fa563fe-f0f7-43eb-9e22-a1ece036b513]
+tempest.api.identity.v3.TestApiDiscovery.test_api_media_types[id-657c1970-4722-4189-8831-7325f3bc4265]
+tempest.api.identity.v3.TestApiDiscovery.test_api_version_resources[id-b9232f5e-d9e5-4d97-b96c-28d3db4de1bd]
+tempest.api.identity.v3.TestApiDiscovery.test_api_version_statuses[id-8879a470-abfb-47bb-bb8d-5a7fd279ad1e]
+tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_media_types[id-657c1970-4722-4189-8831-7325f3bc4265]
+tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_version_resources[id-b9232f5e-d9e5-4d97-b96c-28d3db4de1bd]
+tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_version_statuses[id-8879a470-abfb-47bb-bb8d-5a7fd279ad1e]
+tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_list_api_versions[id-721f480f-35b6-46c7-846e-047e6acea0dc]
+tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_create_application_credential[id-8080c75c-eddc-4786-941a-c2da7039ae61]
+tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_create_application_credential_expires[id-852daf0c-42b5-4239-8466-d193d0543ed3]
+tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_list_application_credentials[id-ff0cd457-6224-46e7-b79e-0ada4964a8a6]
+tempest.api.identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_query_application_credentials[id-9bb5e5cc-5250-493a-8869-8b665f6aa5f6]
+tempest.api.identity.v3.test_catalog.IdentityCatalogTest.test_catalog_standardization[id-56b57ced-22b8-4127-9b8a-565dfb0207e2]
+tempest.api.identity.v3.test_domains.DefaultDomainTestJSON.test_default_domain_exists[id-17a5de24-e6a0-4e4a-a9ee-d85b6e5612b5]
+tempest.api.identity.v3.test_tokens.TokensV3Test.test_create_token[id-6f8e4436-fc96-4282-8122-e41df57197a9]
+tempest.api.identity.v3.test_tokens.TokensV3Test.test_token_auth_creation_existence_deletion[id-0f9f5a5f-d5cd-4a86-8a5b-c5ded151f212]
+tempest.api.identity.v3.test_tokens.TokensV3Test.test_validate_token[id-a9512ac3-3909-48a4-b395-11f438e16260]
+tempest.api.identity.v3.test_users.IdentityV3UsersTest.test_password_history_check_self_service_api[id-941784ee-5342-4571-959b-b80dd2cea516]
+tempest.api.identity.v3.test_users.IdentityV3UsersTest.test_user_account_lockout[id-a7ad8bbf-2cff-4520-8c1d-96332e151658]
+tempest.api.image.v2.test_images.BasicOperationsImagesTest.test_delete_image[id-f848bb94-1c6e-45a4-8726-39e3a5b23535]
+tempest.api.image.v2.test_images.BasicOperationsImagesTest.test_register_upload_get_image_file[id-139b765e-7f3d-4b3d-8b37-3ca3876ee318]
+tempest.api.image.v2.test_images.BasicOperationsImagesTest.test_update_image[id-f66891a7-a35c-41a8-b590-a065c2a1caa6]
+tempest.api.image.v2.test_images.ListImagesTest.test_get_image_schema[id-622b925c-479f-4736-860d-adeaf13bc371]
+tempest.api.image.v2.test_images.ListImagesTest.test_get_images_schema[id-25c8d7b2-df21-460f-87ac-93130bcdc684]
+tempest.api.image.v2.test_images.ListImagesTest.test_index_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_container_format[id-9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_disk_format[id-4a4735a7-f22f-49b6-b0d9-66e1ef7453eb]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_limit[id-e914a891-3cc8-4b40-ad32-e0a39ffbddbb]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_min_max_size[id-4ad8c157-971a-4ba8-aa84-ed61154b1e7f]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_size[id-cf1b9a48-8340-480e-af7b-fe7e17690876]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_status[id-7fc9e369-0f58-4d05-9aa5-0969e2d59d15]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_visibility[id-7a95bb92-d99e-4b12-9718-7bc6ab73e6d2]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_get_image_schema[id-622b925c-479f-4736-860d-adeaf13bc371]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_get_images_schema[id-25c8d7b2-df21-460f-87ac-93130bcdc684]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_container_format[id-9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_disk_format[id-4a4735a7-f22f-49b6-b0d9-66e1ef7453eb]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_limit[id-e914a891-3cc8-4b40-ad32-e0a39ffbddbb]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_min_max_size[id-4ad8c157-971a-4ba8-aa84-ed61154b1e7f]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_size[id-cf1b9a48-8340-480e-af7b-fe7e17690876]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_status[id-7fc9e369-0f58-4d05-9aa5-0969e2d59d15]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_visibility[id-7a95bb92-d99e-4b12-9718-7bc6ab73e6d2]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_delete_image_null_id[id-32248db1-ab88-4821-9604-c7c369f1f88c]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_delete_non_existing_image[id-6fe40f1c-57bd-4918-89cc-8500f850f3de]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_delete_deleted_image[id-e57fc127-7ba0-4693-92d7-1d8a05ebcba9]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_image_null_id[id-ef45000d-0a72-4781-866d-4cb7bf2562ad]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_non_existent_image[id-668743d5-08ad-4480-b2b8-15da34f81d9f]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_register_with_invalid_container_format[id-292bd310-369b-41c7-a7a3-10276ef76753]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_register_with_invalid_disk_format[id-70c6040c-5a97-4111-9e13-e73665264ce1]
+tempest.api.image.v2.test_images_tags.ImagesTagsTest.test_update_delete_tags_for_image[id-10407036-6059-4f95-a2cd-cbbbee7ed329]
+tempest.api.image.v2.test_images_tags_negative.ImagesTagsNegativeTest.test_delete_non_existing_tag[id-39c023a2-325a-433a-9eea-649bf1414b19]
+tempest.api.image.v2.test_images_tags_negative.ImagesTagsNegativeTest.test_update_tags_for_non_existing_image[id-8cd30f82-6f9a-4c6e-8034-c1b51fba43d9]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcp_stateful[id-4ab211a0-276f-4552-9070-51e27f58fecf]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcp_stateful_fixedips[id-51a5e97f-f02e-4e4e-9a17-a69811d300e3]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcp_stateful_fixedips_duplicate[id-57b8302b-cba9-4fbb-8835-9168df029051]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcp_stateful_fixedips_outrange[id-98244d88-d990-4570-91d4-6b25d70d08af]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcp_stateful_router[id-e98f65db-68f4-4330-9fea-abd8c5192d4d]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_64_subnets[id-4256c61d-c538-41ea-9147-3c450c36669e]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_invalid_options[id-81f18ef6-95b5-4584-9966-10d480b7496a]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_stateless_eui64[id-e5517e62-6f16-430d-a672-f80875493d4c]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_stateless_no_ra[id-ae2f4a5d-03ff-4c42-a3b0-ce2fcb7ea832]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_stateless_no_ra_no_dhcp[id-21635b6f-165a-4d42-bf49-7d195e47342f]
+tempest.api.network.test_dhcp_ipv6.NetworksTestDHCPv6.test_dhcpv6_two_subnets[id-4544adf7-bb5f-4bdc-b769-b3e77026cef2]
+tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_create_floating_ip_specifying_a_fixed_ip_address[id-36de4bd0-f09c-43e3-a8e1-1decc1ffd3a5]
+tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_create_update_floatingip_with_port_multiple_ip_address[id-45c4c683-ea97-41ef-9c51-5e9802f2f3d7]
+tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_floating_ip_delete_port[id-e1f6bffd-442f-4668-b30e-df13f2705e77]
+tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_floating_ip_update_different_router[id-1bb2f731-fe5a-4b8c-8409-799ade1bed4d]
+tempest.api.network.test_floating_ips_negative.FloatingIPNegativeTestJSON.test_associate_floatingip_port_ext_net_unreachable[id-6b3b8797-6d43-4191-985c-c48b773eb429]
+tempest.api.network.test_floating_ips_negative.FloatingIPNegativeTestJSON.test_create_floatingip_in_private_network[id-50b9aeb4-9f0b-48ee-aa31-fa955a48ff54]
+tempest.api.network.test_floating_ips_negative.FloatingIPNegativeTestJSON.test_create_floatingip_with_port_ext_net_unreachable[id-22996ea8-4a81-4b27-b6e1-fa5df92fa5e8]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_all_attributes[id-a4d9ec4c-0306-4111-a75c-db01a709030b]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_allocation_pools[id-bec949c4-3147-4ba6-af5f-cd2306118404]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_dhcp_enabled[id-94ce038d-ff0a-4a4c-a56b-09da3ca0b55d]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_gw[id-9393b468-186d-496d-aa36-732348cd76e7]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_gw_and_allocation_pools[id-8217a149-0c6c-4cfb-93db-0486f707d13f]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_host_routes_and_dns_nameservers[id-d830de0a-be47-468f-8f02-1fd996118289]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_without_gateway[id-d2d596e2-8e76-47a9-ac51-d4648009f4d3]
+tempest.api.network.test_networks.NetworksTest.test_create_update_delete_network_subnet[id-0e269138-0da6-4efc-a46d-578161e7b221]
+tempest.api.network.test_networks.NetworksTest.test_delete_network_with_subnet[id-f04f61a9-b7f3-4194-90b2-9bcf660d1bfe]
+tempest.api.network.test_networks.NetworksTest.test_external_network_visibility[id-af774677-42a9-4e4b-bb58-16fe6a5bc1ec]
+tempest.api.network.test_networks.NetworksTest.test_list_networks[id-f7ffdeda-e200-4a7a-bcbe-05716e86bf43]
+tempest.api.network.test_networks.NetworksTest.test_list_networks_fields[id-6ae6d24f-9194-4869-9c85-c313cb20e080]
+tempest.api.network.test_networks.NetworksTest.test_list_subnets[id-db68ba48-f4ea-49e9-81d1-e367f6d0b20a]
+tempest.api.network.test_networks.NetworksTest.test_list_subnets_fields[id-842589e3-9663-46b0-85e4-7f01273b0412]
+tempest.api.network.test_networks.NetworksTest.test_show_network[id-2bf13842-c93f-4a69-83ed-717d2ec3b44e]
+tempest.api.network.test_networks.NetworksTest.test_show_network_fields[id-867819bb-c4b6-45f7-acf9-90edcf70aa5e]
+tempest.api.network.test_networks.NetworksTest.test_show_subnet[id-bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc]
+tempest.api.network.test_networks.NetworksTest.test_show_subnet_fields[id-270fff0b-8bfc-411f-a184-1e8fd35286f0]
+tempest.api.network.test_networks.NetworksTest.test_update_subnet_gw_dns_host_routes_dhcp[id-3d3852eb-3009-49ec-97ac-5ce83b73010a]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_all_attributes[id-a4d9ec4c-0306-4111-a75c-db01a709030b]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_allocation_pools[id-bec949c4-3147-4ba6-af5f-cd2306118404]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_dhcp_enabled[id-94ce038d-ff0a-4a4c-a56b-09da3ca0b55d]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_gw[id-9393b468-186d-496d-aa36-732348cd76e7]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_gw_and_allocation_pools[id-8217a149-0c6c-4cfb-93db-0486f707d13f]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_host_routes_and_dns_nameservers[id-d830de0a-be47-468f-8f02-1fd996118289]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_without_gateway[id-d2d596e2-8e76-47a9-ac51-d4648009f4d3]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_update_delete_network_subnet[id-0e269138-0da6-4efc-a46d-578161e7b221]
+tempest.api.network.test_networks.NetworksTestJSON.test_delete_network_with_subnet[id-f04f61a9-b7f3-4194-90b2-9bcf660d1bfe]
+tempest.api.network.test_networks.NetworksTestJSON.test_external_network_visibility[id-af774677-42a9-4e4b-bb58-16fe6a5bc1ec]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_networks[id-f7ffdeda-e200-4a7a-bcbe-05716e86bf43]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_networks_fields[id-6ae6d24f-9194-4869-9c85-c313cb20e080]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_subnets[id-db68ba48-f4ea-49e9-81d1-e367f6d0b20a]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_subnets_fields[id-842589e3-9663-46b0-85e4-7f01273b0412]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_network[id-2bf13842-c93f-4a69-83ed-717d2ec3b44e]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_network_fields[id-867819bb-c4b6-45f7-acf9-90edcf70aa5e]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_subnet[id-bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_subnet_fields[id-270fff0b-8bfc-411f-a184-1e8fd35286f0]
+tempest.api.network.test_networks.NetworksTestJSON.test_update_subnet_gw_dns_host_routes_dhcp[id-3d3852eb-3009-49ec-97ac-5ce83b73010a]
+tempest.api.network.test_ports.PortsTestJSON.test_create_bulk_port[id-67f1b811-f8db-43e2-86bd-72c074d4a42c]
+tempest.api.network.test_ports.PortsTestJSON.test_create_port_in_allowed_allocation_pools[id-0435f278-40ae-48cb-a404-b8a087bc09b1]
+tempest.api.network.test_ports.PortsTestJSON.test_create_update_delete_port[id-c72c1c0c-2193-4aca-aaa4-b1442640f51c]
+tempest.api.network.test_ports.PortsTestJSON.test_list_ports[id-cf95b358-3e92-4a29-a148-52445e1ac50e]
+tempest.api.network.test_ports.PortsTestJSON.test_list_ports_fields[id-ff7f117f-f034-4e0e-abff-ccef05c454b4]
+tempest.api.network.test_ports.PortsTestJSON.test_port_list_filter_by_router_id[id-5ad01ed0-0e6e-4c5d-8194-232801b15c72]
+tempest.api.network.test_ports.PortsTestJSON.test_show_port[id-c9a685bd-e83f-499c-939f-9f7863ca259f]
+tempest.api.network.test_ports.PortsTestJSON.test_show_port_fields[id-45fcdaf2-dab0-4c13-ac6c-fcddfb579dbd]
+tempest.api.network.test_routers.RoutersTest.test_add_multiple_router_interfaces[id-802c73c9-c937-4cef-824b-2191e24a6aab]
+tempest.api.network.test_routers.RoutersTest.test_add_remove_router_interface_with_port_id[id-2b7d2f37-6748-4d78-92e5-1d590234f0d5]
+tempest.api.network.test_routers.RoutersTest.test_add_remove_router_interface_with_subnet_id[id-b42e6e39-2e37-49cc-a6f4-8467e940900a]
+tempest.api.network.test_routers.RoutersTest.test_create_show_list_update_delete_router[id-f64403e2-8483-4b34-8ccd-b09a87bcc68c]
+tempest.api.network.test_routers.RoutersTest.test_router_interface_port_update_with_fixed_ip[id-96522edf-b4b5-45d9-8443-fa11c26e6eff]
+tempest.api.network.test_routers.RoutersTest.test_update_delete_extra_route[id-c86ac3a8-50bd-4b00-a6b8-62af84a0765c]
+tempest.api.network.test_routers.RoutersTest.test_update_extra_route[id-c86ac3a8-50bd-4b00-a6b8-62af84a0765c]
+tempest.api.network.test_routers.RoutersTest.test_update_router_admin_state[id-a8902683-c788-4246-95c7-ad9c6d63a4d9]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_add_router_interfaces_on_overlapping_subnets_returns_400[id-957751a3-3c68-4fa2-93b6-eb52ea10db6e]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_delete_non_existent_router_returns_404[id-c7edc5ad-d09d-41e6-a344-5c0c31e2e3e4]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_router_add_gateway_invalid_network_returns_404[id-37a94fc0-a834-45b9-bd23-9a81d2fd1e22]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_router_add_gateway_net_not_external_returns_400[id-11836a18-0b15-4327-a50b-f0d9dc66bddd]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_router_remove_interface_in_use_returns_409[id-04df80f9-224d-47f5-837a-bf23e33d1c20]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_show_non_existent_router_returns_404[id-c2a70d72-8826-43a7-8208-0209e6360c47]
+tempest.api.network.test_routers_negative.RoutersNegativeTest.test_update_non_existent_router_returns_404[id-b23d1569-8b0c-4169-8d4b-6abd34fad5c7]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_list_update_show_delete_security_group[id-bfd128e5-3c92-44b6-9d66-7fe29d22c802]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_additional_args[id-87dfbcf9-1849-43ea-b1e4-efa3eeae9f71]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_icmp_type_code[id-c9463db8-b44d-4f52-b6c0-8dbda99f26ce]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_protocol_integer_value[id-0a307599-6655-4220-bebc-fd70c64f2290]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_remote_group_id[id-c2ed2deb-7a0c-44d8-8b4c-a5825b5c310b]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_remote_ip_prefix[id-16459776-5da2-4634-bce4-4b55ee3ec188]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_show_delete_security_group_rule[id-cfb99e0e-7410-4a3d-8a0c-959a63ee77e9]
+tempest.api.network.test_security_groups.SecGroupTest.test_list_security_groups[id-e30abd17-fef9-4739-8617-dc26da88e686]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_additional_default_security_group_fails[id-2323061e-9fbf-4eb0-b547-7e8fafc90849]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_duplicate_security_group_rule_fails[id-8fde898f-ce88-493b-adc9-4e4692879fc5]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_ethertype[id-5666968c-fff3-40d6-9efc-df1c8bd01abb]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_protocol[id-981bdc22-ce48-41ed-900a-73148b583958]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_remote_ip_prefix[id-5f8daf69-3c5f-4aaa-88c9-db1d66f68679]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_invalid_ports[id-0d9c7791-f2ad-4e2f-ac73-abf2373b0d2d]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_non_existent_remote_groupid[id-4bf786fd-2f02-443c-9716-5b98e159a49a]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_non_existent_security_group[id-be308db6-a7cf-4d5c-9baf-71bafd73f35e]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_delete_non_existent_security_group[id-1f1bb89d-5664-4956-9fcd-83ee0fa603df]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_show_non_existent_security_group[id-424fd5c3-9ddc-486a-b45f-39bf0c820fc6]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_show_non_existent_security_group_rule[id-4c094c09-000b-4e41-8100-9617600c02a6]
+tempest.api.network.test_subnetpools_extensions.SubnetPoolsTestJSON.test_create_list_show_update_delete_subnetpools[id-62595970-ab1c-4b7f-8fcc-fddfe55e9811]
+tempest.api.network.test_versions.NetworksApiDiscovery.test_api_version_resources[id-cac8a836-c2e0-4304-b556-cd299c7281d1]
+tempest.api.object_storage.test_account_bulk.BulkTest.test_bulk_delete[id-c075e682-0d2a-43b2-808d-4116200d736d]
+tempest.api.object_storage.test_account_bulk.BulkTest.test_extract_archive[id-a407de51-1983-47cc-9f14-47c2b059413c]
+tempest.api.object_storage.test_account_quotas.AccountQuotasTest.test_upload_valid_object[id-a22ef352-a342-4587-8f47-3bbdb5b039c4]
+tempest.api.object_storage.test_account_quotas_negative.AccountQuotasNegativeTest.test_user_modify_quota[id-d1dc5076-555e-4e6d-9697-28f1fe976324]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers[id-3499406a-ae53-4f8c-b43a-133d4dc6fe3f]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_end_marker[id-5ca164e4-7bde-43fa-bafb-913b53b9e786]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_format_json[id-1c7efa35-e8a2-4b0b-b5ff-862c7fd83704]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_limit[id-5cfa4ab2-4373-48dd-a41f-a532b12b08b2]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_limit_and_end_marker[id-888a3f0e-7214-4806-8e50-5e0c9a69bb5e]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_limit_and_marker[id-f7064ae8-dbcc-48da-b594-82feef6ea5af]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_limit_and_marker_and_end_marker[id-8cf98d9c-e3a0-4e44-971b-c87656fdddbd]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_marker[id-638f876d-6a43-482a-bbb3-0840bca101c6]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_containers_with_marker_and_end_marker[id-ac8502c2-d4e4-4f68-85a6-40befea2ef5e]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_extensions[id-6eb04a6a-4860-4e31-ba91-ea3347d76b58]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_extensions[id-6eb04a6a-4860-4e31-ba91-ea3347d76b58]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_no_account_metadata[id-b904c2e3-24c2-4dba-ad7d-04e90a761be5]
+tempest.api.object_storage.test_account_services.AccountTest.test_list_no_containers[id-884ec421-fbad-4fcc-916b-0580f2699565]
+tempest.api.object_storage.test_account_services.AccountTest.test_update_account_metadata_with_create_metadata_key[id-64fd53f3-adbd-4639-af54-436e4982dbfb]
+tempest.api.object_storage.test_account_services.AccountTest.test_update_account_metadata_with_delete_metadata[id-9f60348d-c46f-4465-ae06-d51dbd470953]
+tempest.api.object_storage.test_account_services.AccountTest.test_update_account_metadata_with_delete_metadata_key[id-d4d884d3-4696-4b85-bc98-4f57c4dd2bf1]
+tempest.api.object_storage.test_container_acl.ObjectTestACLs.test_read_object_with_rights[id-a3270f3f-7640-4944-8448-c7ea783ea5b6]
+tempest.api.object_storage.test_container_acl.ObjectTestACLs.test_write_object_with_rights[id-aa58bfa5-40d9-4bc3-82b4-d07f4a9e392a]
+tempest.api.object_storage.test_container_quotas.ContainerQuotasTest.test_upload_large_object[id-22eeeb2b-3668-4160-baef-44790f65a5a0]
+tempest.api.object_storage.test_container_quotas.ContainerQuotasTest.test_upload_too_many_objects[id-3a387039-697a-44fc-a9c0-935de31f426b]
+tempest.api.object_storage.test_container_quotas.ContainerQuotasTest.test_upload_valid_object[id-9a0fb034-86af-4df0-86fa-f8bd7db21ae0]
+tempest.api.object_storage.test_container_services.ContainerTest.test_create_container[id-92139d73-7819-4db1-85f8-3f2f22a8d91f]
+tempest.api.object_storage.test_container_services.ContainerTest.test_create_container_overwrite[id-49f866ed-d6af-4395-93e7-4187eb56d322]
+tempest.api.object_storage.test_container_services.ContainerTest.test_delete_container[id-95d3a249-b702-4082-a2c4-14bb860cf06a]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents[id-312ff6bd-5290-497f-bda1-7c5fec6697ab]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_delimiter[id-fe323a32-57b9-4704-a996-2e68f83b09bc]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_end_marker[id-55b4fa5c-e12e-4ca9-8fcf-a79afe118522]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_format_json[id-196f5034-6ab0-4032-9da9-a937bbb9fba9]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_limit[id-297ec38b-2b61-4ff4-bcd1-7fa055e97b61]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_marker[id-c31ddc63-2a58-4f6b-b25c-94d2937e6867]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_no_object[id-4646ac2d-9bfb-4c7d-a3c5-0f527402b3df]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_path[id-58ca6cc9-6af0-408d-aaec-2a6a7b2f0df9]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_contents_with_prefix[id-77e742c7-caf2-4ec9-8aa4-f7d509a3344c]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_container_metadata[id-96e68f0e-19ec-4aa2-86f3-adc6a45e14dd]
+tempest.api.object_storage.test_container_services.ContainerTest.test_list_no_container_metadata[id-a2faf936-6b13-4f8d-92a2-c2278355821e]
+tempest.api.object_storage.test_container_services.ContainerTest.test_update_container_metadata_with_create_and_delete_metadata[id-cf19bc0b-7e16-4a5a-aaed-cb0c2fe8deef]
+tempest.api.object_storage.test_container_services.ContainerTest.test_update_container_metadata_with_create_metadata[id-2ae5f295-4bf1-4e04-bfad-21e54b62cec5]
+tempest.api.object_storage.test_container_services.ContainerTest.test_update_container_metadata_with_create_metadata_key[id-31f40a5f-6a52-4314-8794-cd89baed3040]
+tempest.api.object_storage.test_container_services.ContainerTest.test_update_container_metadata_with_delete_metadata[id-3a5ce7d4-6e4b-47d0-9d87-7cd42c325094]
+tempest.api.object_storage.test_container_services.ContainerTest.test_update_container_metadata_with_delete_metadata_key[id-a2e36378-6f1f-43f4-840a-ffd9cfd61914]
+tempest.api.object_storage.test_object_expiry.ObjectExpiryTest.test_get_object_after_expiry_time[id-fb024a42-37f3-4ba5-9684-4f40a7910b41]
+tempest.api.object_storage.test_object_services.ObjectTest.test_copy_object_2d_way[id-06f90388-2d0e-40aa-934c-e9a8833e958a]
+tempest.api.object_storage.test_object_services.ObjectTest.test_copy_object_across_containers[id-aa467252-44f3-472a-b5ae-5b57c3c9c147]
+tempest.api.object_storage.test_object_services.ObjectTest.test_copy_object_in_same_container[id-1a9ab572-1b66-4981-8c21-416e2a5e6011]
+tempest.api.object_storage.test_object_services.ObjectTest.test_copy_object_to_itself[id-2248abba-415d-410b-9c30-22dff9cd6e67]
+tempest.api.object_storage.test_object_services.ObjectTest.test_create_object[id-5b4ce26f-3545-46c9-a2ba-5754358a4c62]
+tempest.api.object_storage.test_object_services.ObjectTest.test_delete_object[id-17738d45-03bd-4d45-9e0b-7b2f58f98687]
+tempest.api.object_storage.test_object_services.ObjectTest.test_get_object[id-02610ba7-86b7-4272-9ed8-aa8d417cb3cd]
+tempest.api.object_storage.test_object_services.ObjectTest.test_get_object_if_different[id-50d01f12-526f-4360-9ac2-75dd508d7b68]
+tempest.api.object_storage.test_object_services.ObjectTest.test_get_object_with_x_object_manifest[id-e3e6a64a-9f50-4955-b987-6ce6767c97fb]
+tempest.api.object_storage.test_object_services.ObjectTest.test_list_object_metadata_with_x_object_manifest[id-23a3674c-d6de-46c3-86af-ff92bfc8a3da]
+tempest.api.object_storage.test_object_services.ObjectTest.test_object_upload_in_segments[id-e3e6a64a-9f50-4955-b987-6ce6767c97fb]
+tempest.api.object_storage.test_object_services.ObjectTest.test_object_upload_in_segments[id-e3e6a64a-9f50-4955-b987-6ce6767c97fb]
+tempest.api.object_storage.test_object_slo.ObjectSloTest.test_delete_large_object[id-87b6dfa1-abe9-404d-8bf0-6c3751e6aa77]
+tempest.api.object_storage.test_object_slo.ObjectSloTest.test_list_large_object_metadata[id-e69ad766-e1aa-44a2-bdd2-bf62c09c1456]
+tempest.api.object_storage.test_object_slo.ObjectSloTest.test_retrieve_large_object[id-49bc49bc-dd1b-4c0f-904e-d9f10b830ee8]
+tempest.api.object_storage.test_object_slo.ObjectSloTest.test_upload_manifest[id-2c3f24a6-36e8-4711-9aa2-800ee1fc7b5b]
+tempest.api.object_storage.test_object_temp_url.ObjectTempUrlTest.test_get_object_using_temp_url[id-f91c96d4-1230-4bba-8eb9-84476d18d991]
+tempest.api.object_storage.test_object_temp_url.ObjectTempUrlTest.test_put_object_using_temp_url[id-9b08dade-3571-4152-8a4f-a4f2a873a735]
+tempest.api.object_storage.test_object_version.ContainerTest.test_versioned_container[id-a151e158-dcbf-4a1f-a1e7-46cd65895a6f]
+tempest.api.volume.test_availability_zone.AvailabilityZoneTestJSON.test_get_availability_zone_list[id-01f1ae88-eba9-4c6b-a011-6f7ace06b725]
+tempest.api.volume.test_availability_zone.AvailabilityZoneV2TestJSON.test_get_availability_zone_list[id-01f1ae88-eba9-4c6b-a011-6f7ace06b725]
+tempest.api.volume.test_extensions.ExtensionsTestJSON.test_list_extensions[id-94607eb0-43a5-47ca-82aa-736b41bd2e2c]
+tempest.api.volume.test_extensions.ExtensionsV2TestJSON.test_list_extensions[id-94607eb0-43a5-47ca-82aa-736b41bd2e2c]
+tempest.api.volume.test_snapshot_metadata.SnapshotMetadataTestJSON.test_crud_snapshot_metadata[id-a2f20f99-e363-4584-be97-bc33afb1a56c]
+tempest.api.volume.test_snapshot_metadata.SnapshotMetadataTestJSON.test_update_show_snapshot_metadata_item[id-e8ff85c5-8f97-477f-806a-3ac364a949ed]
+tempest.api.volume.test_snapshot_metadata.SnapshotMetadataTestJSON.test_update_snapshot_metadata_item[id-e8ff85c5-8f97-477f-806a-3ac364a949ed]
+tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_create_get_delete_snapshot_metadata[id-a2f20f99-e363-4584-be97-bc33afb1a56c]
+tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_crud_snapshot_metadata[id-a2f20f99-e363-4584-be97-bc33afb1a56c]
+tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_update_snapshot_metadata_item[id-e8ff85c5-8f97-477f-806a-3ac364a949ed]
+tempest.api.volume.test_versions.VersionsTest.test_list_versions[id-77838fc4-b49b-4c64-9533-166762517369]
+tempest.api.volume.test_volume_metadata.VolumesMetadataTest.test_create_get_delete_volume_metadata[id-6f5b125b-f664-44bf-910f-751591fe5769]
+tempest.api.volume.test_volume_metadata.VolumesMetadataTest.test_crud_volume_metadata[id-6f5b125b-f664-44bf-910f-751591fe5769]
+tempest.api.volume.test_volume_metadata.VolumesMetadataTest.test_update_show_volume_metadata_item[id-862261c5-8df4-475a-8c21-946e50e36a20]
+tempest.api.volume.test_volume_metadata.VolumesMetadataTest.test_update_volume_metadata_item[id-862261c5-8df4-475a-8c21-946e50e36a20]
+tempest.api.volume.test_volume_metadata.VolumesV2MetadataTest.test_create_get_delete_volume_metadata[id-6f5b125b-f664-44bf-910f-751591fe5769]
+tempest.api.volume.test_volume_metadata.VolumesV2MetadataTest.test_update_volume_metadata_item[id-862261c5-8df4-475a-8c21-946e50e36a20]
+tempest.api.volume.test_volumes_actions.VolumesActionsTest.test_volume_bootable[id-63e21b4c-0a0c-41f6-bfc3-7c2816815599]
+tempest.api.volume.test_volumes_actions.VolumesActionsTest.test_volume_readonly_update[id-fff74e1e-5bd3-4b33-9ea9-24c103bc3f59]
+tempest.api.volume.test_volumes_actions.VolumesActionsTest.test_volume_upload[id-d8f1ca95-3d5b-44a3-b8ca-909691c9532d]
+tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_volume_bootable[id-63e21b4c-0a0c-41f6-bfc3-7c2816815599]
+tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_volume_readonly_update[id-fff74e1e-5bd3-4b33-9ea9-24c103bc3f59]
+tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_volume_upload[id-d8f1ca95-3d5b-44a3-b8ca-909691c9532d]
+tempest.api.volume.test_volumes_get.VolumesGetTest.test_volume_create_get_update_delete[id-27fb0e9f-fb64-41dd-8bdb-1ffa762f0d51]
+tempest.api.volume.test_volumes_get.VolumesGetTest.test_volume_create_get_update_delete_as_clone[id-3f591b4a-7dc6-444c-bd51-77469506b3a1]
+tempest.api.volume.test_volumes_get.VolumesGetTest.test_volume_create_get_update_delete_from_image[id-54a01030-c7fc-447c-86ee-c1182beae638]
+tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete[id-27fb0e9f-fb64-41dd-8bdb-1ffa762f0d51]
+tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete_as_clone[id-3f591b4a-7dc6-444c-bd51-77469506b3a1]
+tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete_from_image[id-54a01030-c7fc-447c-86ee-c1182beae638]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list[id-0b6ddd39-b948-471f-8038-4787978747c4]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_by_name[id-a28e8da4-0b56-472f-87a8-0f4d3f819c02]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_details_by_name[id-2de3a6d4-12aa-403b-a8f2-fdeb42a89623]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_details_pagination[id-e9138a2c-f67b-4796-8efa-635c196d01de]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_details_with_multiple_params[id-2a7064eb-b9c3-429b-b888-33928fc5edd3]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_pagination[id-af55e775-8e4b-4feb-8719-215c43b0238c]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_param_display_name_and_status[id-777c87c1-2fc4-4883-8b8e-5c0b951d1ec8]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_with_detail_param_display_name_and_status[id-856ab8ca-6009-4c37-b691-be1065528ad4]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_with_detail_param_metadata[id-1ca92d3c-4a8e-4b43-93f5-e4c7fb3b291d]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_with_details[id-adcbb5a7-5ad8-4b61-bd10-5380e111a877]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volume_list_with_param_metadata[id-b5ebea1b-0603-40a0-bb41-15fcd0a53214]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volumes_list_by_availability_zone[id-c0cfa863-3020-40d7-b587-e35f597d5d87]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volumes_list_by_status[id-39654e13-734c-4dab-95ce-7613bf8407ce]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volumes_list_details_by_availability_zone[id-e1b80d13-94f0-4ba2-a40e-386af29f8db1]
+tempest.api.volume.test_volumes_list.VolumesListTestJSON.test_volumes_list_details_by_status[id-2943f712-71ec-482a-bf49-d5ca06216b9f]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list[id-0b6ddd39-b948-471f-8038-4787978747c4]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_by_name[id-a28e8da4-0b56-472f-87a8-0f4d3f819c02]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_by_name[id-2de3a6d4-12aa-403b-a8f2-fdeb42a89623]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_param_display_name_and_status[id-777c87c1-2fc4-4883-8b8e-5c0b951d1ec8]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_detail_param_display_name_and_status[id-856ab8ca-6009-4c37-b691-be1065528ad4]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_detail_param_metadata[id-1ca92d3c-4a8e-4b43-93f5-e4c7fb3b291d]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_details[id-adcbb5a7-5ad8-4b61-bd10-5380e111a877]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_param_metadata[id-b5ebea1b-0603-40a0-bb41-15fcd0a53214]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_by_availability_zone[id-c0cfa863-3020-40d7-b587-e35f597d5d87]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_by_status[id-39654e13-734c-4dab-95ce-7613bf8407ce]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_details_by_availability_zone[id-e1b80d13-94f0-4ba2-a40e-386af29f8db1]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_details_by_status[id-2943f712-71ec-482a-bf49-d5ca06216b9f]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_invalid_size[id-1ed83a8a-682d-4dfb-a30e-ee63ffd6c049]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_nonexistent_snapshot_id[id-0c36f6ae-4604-4017-b0a9-34fdc63096f9]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_nonexistent_source_volid[id-47c73e08-4be8-45bb-bfdf-0c4e79b88344]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_nonexistent_volume_type[id-10254ed8-3849-454e-862e-3ab8e6aa01d2]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_size_negative[id-8b472729-9eba-446e-a83b-916bdb34bef7]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_with_size_zero[id-41331caa-eaf4-4001-869d-bc18c1869360]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_create_volume_without_passing_size[id-9387686f-334f-4d31-a439-33494b9e2683]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_delete_invalid_volume_id[id-1f035827-7c32-4019-9240-b4ec2dbd9dfd]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_delete_volume_without_passing_volume_id[id-441a1550-5d44-4b30-af0f-a6d402f52026]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_get_invalid_volume_id[id-30799cfd-7ee4-446c-b66c-45b383ed211b]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_get_volume_without_passing_volume_id[id-c6c3db06-29ad-4e91-beb0-2ab195fe49e3]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_list_volumes_detail_with_invalid_status[id-ba94b27b-be3f-496c-a00e-0283b373fa75]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_list_volumes_detail_with_nonexistent_name[id-9ca17820-a0e7-4cbd-a7fa-f4468735e359]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_list_volumes_with_invalid_status[id-143b279b-7522-466b-81be-34a87d564a7c]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_list_volumes_with_nonexistent_name[id-0f4aa809-8c7b-418f-8fb3-84c7a5dfc52f]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_update_volume_with_empty_volume_id[id-72aeca85-57a5-4c1f-9057-f320f9ea575b]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_update_volume_with_invalid_volume_id[id-e66e40d6-65e6-4e75-bdc7-636792fa152d]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_update_volume_with_nonexistent_volume_id[id-0186422c-999a-480e-a026-6a665744c30c]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_volume_delete_nonexistent_volume_id[id-555efa6e-efcd-44ef-8a3b-4a7ca4837a29]
+tempest.api.volume.test_volumes_negative.VolumesNegativeTest.test_volume_get_nonexistent_volume_id[id-f131c586-9448-44a4-a8b0-54ca838aa43e]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_invalid_size[id-1ed83a8a-682d-4dfb-a30e-ee63ffd6c049]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_snapshot_id[id-0c36f6ae-4604-4017-b0a9-34fdc63096f9]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_source_volid[id-47c73e08-4be8-45bb-bfdf-0c4e79b88344]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_volume_type[id-10254ed8-3849-454e-862e-3ab8e6aa01d2]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_out_passing_size[id-9387686f-334f-4d31-a439-33494b9e2683]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_size_negative[id-8b472729-9eba-446e-a83b-916bdb34bef7]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_size_zero[id-41331caa-eaf4-4001-869d-bc18c1869360]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_without_passing_size[id-9387686f-334f-4d31-a439-33494b9e2683]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_delete_invalid_volume_id[id-1f035827-7c32-4019-9240-b4ec2dbd9dfd]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_delete_volume_without_passing_volume_id[id-441a1550-5d44-4b30-af0f-a6d402f52026]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_get_invalid_volume_id[id-30799cfd-7ee4-446c-b66c-45b383ed211b]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_get_volume_without_passing_volume_id[id-c6c3db06-29ad-4e91-beb0-2ab195fe49e3]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_detail_with_invalid_status[id-ba94b27b-be3f-496c-a00e-0283b373fa75]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_detail_with_nonexistent_name[id-9ca17820-a0e7-4cbd-a7fa-f4468735e359]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_with_invalid_status[id-143b279b-7522-466b-81be-34a87d564a7c]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_with_nonexistent_name[id-0f4aa809-8c7b-418f-8fb3-84c7a5dfc52f]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_empty_volume_id[id-72aeca85-57a5-4c1f-9057-f320f9ea575b]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_invalid_volume_id[id-e66e40d6-65e6-4e75-bdc7-636792fa152d]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_nonexistent_volume_id[id-0186422c-999a-480e-a026-6a665744c30c]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_volume_delete_nonexistent_volume_id[id-555efa6e-efcd-44ef-8a3b-4a7ca4837a29]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_volume_get_nonexistent_volume_id[id-f131c586-9448-44a4-a8b0-54ca838aa43e]
+tempest.api.volume.test_volumes_snapshots.VolumesSnapshotTestJSON.test_snapshot_create_get_list_update_delete[id-2a8abbe4-d871-46db-b049-c41f5af8216e]
+tempest.api.volume.test_volumes_snapshots.VolumesSnapshotTestJSON.test_volume_from_snapshot[id-677863d1-3142-456d-b6ac-9924f667a7f4]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshot_create_get_list_update_delete[id-2a8abbe4-d871-46db-b049-c41f5af8216e]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshots_list_details_with_params[id-220a1022-1fcd-4a74-a7bd-6b859156cda2]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshots_list_with_params[id-59f41f43-aebf-48a9-ab5d-d76340fab32b]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_volume_from_snapshot[id-677863d1-3142-456d-b6ac-9924f667a7f4]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_limit[id-db4d8e0a-7a2e-41cc-a712-961f6844e896]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_limit_equals_infinite[id-a1427f61-420e-48a5-b6e3-0b394fa95400]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_limit_equals_zero[id-e3b44b7f-ae87-45b5-8a8c-66110eb24d0a]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_marker[id-05489dde-44bc-4961-a1f5-3ce7ee7824f7]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_offset[id-ca96d551-17c6-4e11-b0e8-52d3bb8a63c7]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_created_at_asc[id-4052c3a0-2415-440a-a8cc-305a875331b0]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_created_at_desc[id-dcbbe24a-f3c0-4ec8-9274-55d48db8d1cf]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_id_asc[id-c5513ada-64c1-4d28-83b9-af3307ec1388]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_id_desc[id-8a7fe058-0b41-402a-8afd-2dbc5a4a718b]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_name_asc[id-d58b5fed-0c37-42d3-8c5d-39014ac13c00]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshot_list_param_sort_name_desc[id-96ba6f4d-1f18-47e1-b4bc-76edc6c21250]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshots_list_details_with_params[id-220a1022-1fcd-4a74-a7bd-6b859156cda2]
+tempest.api.volume.test_volumes_snapshots_list.VolumesSnapshotListTestJSON.test_snapshots_list_with_params[id-59f41f43-aebf-48a9-ab5d-d76340fab32b]
+tempest.api.volume.test_volumes_snapshots_list.VolumesV2SnapshotListTestJSON.test_snapshots_list_details_with_params[id-220a1022-1fcd-4a74-a7bd-6b859156cda2]
+tempest.api.volume.test_volumes_snapshots_list.VolumesV2SnapshotListTestJSON.test_snapshots_list_with_params[id-59f41f43-aebf-48a9-ab5d-d76340fab32b]
+tempest.api.volume.test_volumes_snapshots_negative.VolumesSnapshotNegativeTestJSON.test_create_snapshot_with_nonexistent_volume_id[id-e3e466af-70ab-4f4b-a967-ab04e3532ea7]
+tempest.api.volume.test_volumes_snapshots_negative.VolumesSnapshotNegativeTestJSON.test_create_snapshot_without_passing_volume_id[id-bb9da53e-d335-4309-9c15-7e76fd5e4d6d]
+tempest.api.volume.test_volumes_snapshots_negative.VolumesV2SnapshotNegativeTestJSON.test_create_snapshot_with_nonexistent_volume_id[id-e3e466af-70ab-4f4b-a967-ab04e3532ea7]
+tempest.api.volume.test_volumes_snapshots_negative.VolumesV2SnapshotNegativeTestJSON.test_create_snapshot_without_passing_volume_id[id-bb9da53e-d335-4309-9c15-7e76fd5e4d6d]
+tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_pagination[id-e9138a2c-f67b-4796-8efa-635c196d01de]
+tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_with_multiple_params[id-2a7064eb-b9c3-429b-b888-33928fc5edd3]
+tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_pagination[id-af55e775-8e4b-4feb-8719-215c43b0238c]
diff --git a/docker/smoke/testcases.yaml b/docker/smoke/testcases.yaml
index 55f7a102a..77bee5704 100644
--- a/docker/smoke/testcases.yaml
+++ b/docker/smoke/testcases.yaml
@@ -2,42 +2,91 @@
tiers:
-
name: smoke
- order: 1
description: >-
Set of basic Functional tests to validate the OPNFV scenarios.
testcases:
-
- case_name: tempest_smoke
+ case_name: tempest_neutron
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case runs the smoke subset of the OpenStack
- Tempest suite. The list of test cases is generated by
+ This test case runs the Tempest suite proposed by the
+ Neutron project. The list of test cases is generated by
Tempest automatically and depends on the parameters of
- the OpenStack deplopyment.
- https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L114
+ the OpenStack deployment.
run:
name: tempest_common
args:
- mode: '(?=.*\[.*\bsmoke\b.*\])(^tempest\.api)'
+ mode: '^neutron_tempest_plugin\.api'
option:
- '--concurrency=4'
-
- case_name: neutron-tempest-plugin-api
+ case_name: tempest_cinder
project_name: functest
criteria: 100
blocking: false
description: >-
This test case runs the Tempest suite proposed by the
- Neutron project. The list of test cases is generated by
- Tempest automatically and depends on the parameters of
- the OpenStack deployment.
+ Cinder project.
run:
name: tempest_common
args:
- mode: '^neutron_tempest_plugin\.api'
+ mode: "(?!.*test_incremental_backup)\
+ (?!.*test_backup_crossproject_admin_negative)\
+ (?!.*test_backup_crossproject_user_negative)\
+ (^cinder_tempest_plugin.)"
+ option:
+ - '--concurrency=4'
+
+ -
+ case_name: tempest_keystone
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs the Tempest suite proposed by the
+ Keystone project.
+ run:
+ name: tempest_common
+ args:
+ mode: 'keystone_tempest_plugin.'
+ option:
+ - '--concurrency=4'
+
+ -
+ case_name: tempest_heat
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs the Tempest suite proposed by the
+ Heat project.
+ run:
+ name: tempest_heat
+ args:
+ mode: '^heat_tempest_plugin.tests'
+ option:
+ - '--concurrency=1'
+
+ -
+ case_name: tempest_telemetry
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs the Tempest suite proposed by the
+ Telemetry project.
+ run:
+ name: tempest_common
+ args:
+ mode: "(?!.*test_autoscaling)(?!.*test_live)\
+ (^telemetry_tempest_plugin)"
+ services:
+ - aodh
+ - gnocchi
+ - panko
option:
- '--concurrency=4'
@@ -51,123 +100,251 @@ tiers:
Rally suite in smoke mode.
run:
name: rally_sanity
+ args:
+ optional:
+ - 'gnocchi'
+ - 'barbican'
-
- case_name: rally_jobs
+ case_name: refstack_compute
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case runs a group of Rally jobs used in
- OpenStack gating
+ This test case runs a sub group of tests of the OpenStack
+ Compute testcases.
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
- name: rally_jobs
+ name: refstack
+ args:
+ target: compute
+ option:
+ - '--concurrency=4'
-
- case_name: refstack_defcore
+ case_name: refstack_object
project_name: functest
criteria: 100
blocking: false
description: >-
This test case runs a sub group of tests of the OpenStack
- Defcore testcases.
+ Object testcases.
run:
- name: refstack_defcore
+ name: refstack
args:
+ target: object
option:
- '--concurrency=4'
-
- case_name: patrole
+ case_name: refstack_platform
project_name: functest
criteria: 100
blocking: false
description: >-
- Test suite from Patrole project.
+ This test case runs a sub group of tests of the OpenStack
+ Platform testcases.
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
- name: patrole
+ name: refstack
args:
- role: 'admin'
- includes:
- - 'image'
- - 'network'
- excludes:
- - 'test_networks_multiprovider_rbac'
- - 'test_auto_allocated_topology_rbac'
+ target: platform
+ option:
+ - '--concurrency=4'
-
- case_name: snaps_smoke
+ case_name: tempest_full
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case contains tests that setup and destroy
- environments with VMs with and without Floating IPs
- with a newly created user and project. Set the config
- value snaps.use_floating_ips (True|False) to toggle
- this functionality. When the config value of
- snaps.use_keystone is True, functest must have access to
- the cloud's private network.
+ The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L83
run:
- name: snaps_smoke
+ name: tempest_common
+ args:
+ mode: '(?!.*\[.*\bslow\b.*\])(^tempest\.api)'
+ option:
+ - '--concurrency=4'
-
- case_name: neutron_trunk
+ case_name: tempest_scenario
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case runs the neutron trunk subtest of the
- OpenStack Tempest suite. The list of test cases is
- generated by Tempest having as input the relevant
- testcase list file.
+ The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L84
run:
name: tempest_common
args:
- mode: 'neutron_tempest_plugin.(api|scenario).test_trunk'
- neutron_extensions:
- - trunk
- - trunk-details
+ mode: '(?!.*\[.*\bslow\b.*\])(^tempest\.scenario)'
+ option:
+ - '--concurrency=1'
-
- case_name: networking-bgpvpn
+ case_name: tempest_slow
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case runs OpenStack networking-bgpvpn Tempest
- suite. The list of test cases is generated by Tempest
- having as input the relevant regex.
+ The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L84
run:
name: tempest_common
args:
- mode: '^networking_bgpvpn_tempest\.'
- neutron_extensions:
- - bgpvpn
+ mode: '(?=.*\[.*\bslow\b.*\])(^tempest\.)'
+ option:
+ - '--concurrency=1'
+
+ -
+ case_name: patrole_admin
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ Test suite from Patrole project.
+ run:
+ name: patrole
+ args:
+ roles: 'admin'
+ mode: "(?!.*test_unmanage_snapshot_rbac)\
+ (?!.*test_show_auto_allocated_topology)\
+ (?!.*test_delete_auto_allocated_topology)\
+ (?!.*test_create_network_provider_segmentation_id)\
+ (?!.*compute.test_floating_ips_rbac)\
+ (?!.*test_reset_network)\
+ (?!.*test_create_image_from_volume_backed_server)\
+ (?!.*test_network_ip_availability_rbac.NetworkIpAvailabilityExtRbacTest.test_get_network_ip_availabilities)\
+ (?!.*test_policy_bandwidth_limit_rule_rbac)\
+ (?!.*test_policy_minimum_bandwidth_rule_rbac)\
+ (?!.*test_group_type_specs)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_create_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_delete_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_update_group_type)\
+ (?!.*test_group_snapshots_rbac)\
+ (?!.*test_groups_rbac)\
+ (?!.*test_quota_classes_rbac)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_create_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_delete_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_show_interface)\
+ (?!.*test_user_messages_rbac)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV310RbacTest)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV312RbacTest)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_delete_volume_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_list_volumes_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_show_volume_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_update_volume_image_metadata)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV318RbacTest)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV39RbacTest)\
+ (?!.*test_volume_types_rbac)\
+ (?=.*[.*\bslow\b.*])\
+ (^patrole_tempest_plugin.tests.api.(compute|image|network|volume))"
option:
- '--concurrency=4'
-
- case_name: networking-sfc
+ case_name: patrole_member
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case runs OpenStack networking-sfc Tempest
- suite. The list of test cases is generated by Tempest
- having as input the relevant regex.
+ Test suite from Patrole project.
run:
- name: tempest_common
+ name: patrole
args:
- mode:
- '^(?:networking_sfc\.tests\.tempest_plugin.tests.api).*$'
- neutron_extensions:
- - sfc
+ roles: 'member'
+ mode: "(?!.*test_unmanage_snapshot_rbac)\
+ (?!.*test_show_auto_allocated_topology)\
+ (?!.*test_delete_auto_allocated_topology)\
+ (?!.*test_create_network_provider_segmentation_id)\
+ (?!.*compute.test_floating_ips_rbac)\
+ (?!.*test_reset_network)\
+ (?!.*test_create_image_from_volume_backed_server)\
+ (?!.*test_network_ip_availability_rbac.NetworkIpAvailabilityExtRbacTest.test_get_network_ip_availabilities)\
+ (?!.*test_policy_bandwidth_limit_rule_rbac)\
+ (?!.*test_policy_minimum_bandwidth_rule_rbac)\
+ (?!.*test_group_type_specs)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_create_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_delete_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_update_group_type)\
+ (?!.*test_group_snapshots_rbac)\
+ (?!.*test_groups_rbac)\
+ (?!.*test_quota_classes_rbac)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_create_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_delete_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_show_interface)\
+ (?!.*test_user_messages_rbac)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV310RbacTest)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV312RbacTest)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_delete_volume_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_list_volumes_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_show_volume_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_update_volume_image_metadata)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV318RbacTest)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV39RbacTest)\
+ (?!.*test_volume_types_rbac)\
+ (?=.*[.*\bslow\b.*])\
+ (^patrole_tempest_plugin.tests.api.(compute|image|network|volume))"
option:
- - '--concurrency=0'
+ - '--concurrency=4'
-
- case_name: barbican
+ case_name: patrole_reader
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ Test suite from Patrole project.
+ run:
+ name: patrole
+ args:
+ roles: 'reader'
+ mode: "(?!.*test_unmanage_snapshot_rbac)\
+ (?!.*test_show_auto_allocated_topology)\
+ (?!.*test_delete_auto_allocated_topology)\
+ (?!.*test_create_network_provider_segmentation_id)\
+ (?!.*compute.test_floating_ips_rbac)\
+ (?!.*test_reset_network)\
+ (?!.*test_create_image_from_volume_backed_server)\
+ (?!.*test_network_ip_availability_rbac.NetworkIpAvailabilityExtRbacTest.test_get_network_ip_availabilities)\
+ (?!.*test_policy_bandwidth_limit_rule_rbac)\
+ (?!.*test_policy_minimum_bandwidth_rule_rbac)\
+ (?!.*test_group_type_specs)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_create_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_delete_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_update_group_type)\
+ (?!.*test_group_snapshots_rbac)\
+ (?!.*test_groups_rbac)\
+ (?!.*test_quota_classes_rbac)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_create_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_delete_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_show_interface)\
+ (?!.*test_user_messages_rbac)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV310RbacTest)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV312RbacTest)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_delete_volume_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_list_volumes_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_show_volume_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_update_volume_image_metadata)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV318RbacTest)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV39RbacTest)\
+ (?!.*test_volume_types_rbac)\
+ (?=.*[.*\bslow\b.*])\
+ (^patrole_tempest_plugin.tests.api.(compute|image|network|volume))"
+ option:
+ - '--concurrency=4'
+
+ -
+ case_name: tempest_barbican
project_name: functest
criteria: 100
blocking: false
@@ -181,3 +358,43 @@ tiers:
'^barbican_tempest_plugin.((?!test_signed_image_upload_boot_failure).)*$'
services:
- barbican
+ option:
+ - '--concurrency=4'
+
+ -
+ case_name: tempest_octavia
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ It leverages on the tempest plugin containing tests used to
+ verify the functionality of an octavia installation.
+ run:
+ name: tempest_common
+ args:
+ mode: "(?!.*api.v2.test_availability_zone)\
+ (?!.*api.v2.test_availability_zone_profile)\
+ (?!.*api.v2.test_member.MemberAPITest.test_member_ipv4_create)\
+ (?!.*api.v2.test_member.MemberAPITest.test_member_ipv6_create)\
+ (^octavia_tempest_plugin.tests.(api|scenario))"
+ services:
+ - octavia
+ option:
+ - '--concurrency=2'
+
+ -
+ case_name: tempest_cyborg
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ It leverages on the tempest plugin containing tests used to
+ verify the functionality of a cyborg installation.
+ run:
+ name: tempest_common
+ args:
+ mode: '^cyborg_tempest_plugin'
+ services:
+ - cyborg
+ option:
+ - '--concurrency=4'
diff --git a/docker/tempest/Dockerfile b/docker/tempest/Dockerfile
deleted file mode 100644
index 9174a495c..000000000
--- a/docker/tempest/Dockerfile
+++ /dev/null
@@ -1,40 +0,0 @@
-FROM opnfv/functest-core
-
-ARG BRANCH=master
-ARG OPENSTACK_TAG=master
-ARG RALLY_TAG=1.1.0
-ARG RALLY_OPENSTACK_TAG=67882d55ca453d6aa863d279ec4cfc2b52c80f0a
-ARG OS_FAULTS_TAG=0.1.17
-
-RUN apk --no-cache add --virtual .build-deps --update \
- python-dev build-base linux-headers libffi-dev \
- openssl-dev libjpeg-turbo-dev && \
- wget -q -O- https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=$OPENSTACK_TAG | \
- sed -E s/^tempest==+.*$/-e\ git+https:\\/\\/git.openstack.org\\/openstack\\/tempest#egg=tempest/ \
- > upper-constraints.txt && \
- wget -q -O- https://git.opnfv.org/functest/plain/upper-constraints.txt?h=$BRANCH | \
- sed -E /#egg=functest/d > upper-constraints.opnfv.txt && \
- git init /src/os-faults && \
- (cd /src/os-faults && \
- git fetch --tags https://git.openstack.org/openstack/os-faults.git $OS_FAULTS_TAG && \
- git checkout FETCH_HEAD) && \
- update-requirements -s --source /src/openstack-requirements /src/os-faults/ && \
- git init /src/rally && \
- (cd /src/rally && \
- git fetch --tags https://git.openstack.org/openstack/rally.git $RALLY_TAG && \
- git checkout FETCH_HEAD) && \
- update-requirements -s --source /src/openstack-requirements /src/rally/ && \
- git init /src/rally-openstack && \
- (cd /src/rally-openstack && \
- git fetch --tags https://git.openstack.org/openstack/rally-openstack.git $RALLY_OPENSTACK_TAG && \
- git checkout FETCH_HEAD) && \
- update-requirements -s --source /src/openstack-requirements /src/rally-openstack && \
- pip install --no-cache-dir --src /src -cupper-constraints.txt -cupper-constraints.opnfv.txt \
- tempest /src/rally-openstack /src/os-faults && \
- pip install --no-cache-dir --src /src -cupper-constraints.txt -cupper-constraints.opnfv.txt \
- /src/rally && \
- rm -r upper-constraints.txt upper-constraints.opnfv.txt /src/os-faults /src/rally /src/rally-openstack && \
- mkdir -p /etc/rally && \
- printf "[database]\nconnection = 'sqlite:////var/lib/rally/database/rally.sqlite'" > /etc/rally/rally.conf && \
- mkdir -p /var/lib/rally/database && rally db create && \
- apk del .build-deps
diff --git a/docker/tempest/hooks/post_checkout b/docker/tempest/hooks/post_checkout
deleted file mode 100644
index 8d0e98124..000000000
--- a/docker/tempest/hooks/post_checkout
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-from="${DOCKER_REPO%/*}/functest-core:${DOCKER_TAG}"
-sed -i "s|^FROM.*$|FROM ${from}|" Dockerfile
-
-exit $?
diff --git a/docker/vnf/Dockerfile b/docker/vnf/Dockerfile
index 0b39b480e..99f848fcd 100644
--- a/docker/vnf/Dockerfile
+++ b/docker/vnf/Dockerfile
@@ -1,32 +1,23 @@
FROM opnfv/functest-core
-ARG BRANCH=master
-ARG OPENSTACK_TAG=master
-ARG VIMS_TEST_TAG=release-129
+ARG VIMS_TEST_TAG=release-130
ARG QUAFF_TAG=59213d6d8ee29433552bb75f505cdc96b0b18909
-ARG CLOUDIFY_VIMS_TAG=fraser
-ARG HEAT_VIMS_TAG=release-129
+ARG CLOUDIFY_VIMS_TAG=gambia
+ARG HEAT_VIMS_TAG=release-130
ARG VROUTER_TAG=fraser
-ARG JUJU_TAG=tags/juju-2.3.9
-ARG JUJU_WAIT_TAG=2.6.4
+ARG VROUTER_BP_TAG=9b76d46a388d32d4985797620e67c2ed3315b3e4
ARG ABOT_CHARM=opnfv-fraser
-ARG GODEPS_TAG=404a7e748cd352bb0d7449dedc645546eebbfc6e
-
-ENV GOPATH /src/epc-requirements/go
-ENV GOBIN /src/epc-requirements/go/bin
-ENV PATH $GOBIN:$PATH
+COPY clearwater-heat-singlenet-deps.patch /tmp/clearwater-heat-singlenet-deps.patch
RUN apk --no-cache add --update \
- ruby ruby-bundler ruby-irb ruby-rdoc dnsmasq \
- procps libxslt libxml2 zlib libffi python3 go musl-dev && \
+ ruby ruby-bundler ruby-irb ruby-rdoc \
+ procps libxslt libxml2 zlib libffi musl-dev && \
apk --no-cache add --virtual .build-deps --update \
- ruby-dev g++ make libxslt-dev libxml2-dev zlib-dev libffi-dev g++ make && \
- wget -q -O- https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=$OPENSTACK_TAG | \
- sed -E s/^tempest==+\(.*\)$/-e\ git+https:\\/\\/git.openstack.org\\/openstack\\/tempest@\\1#egg=tempest/ \
- > upper-constraints.txt && \
- wget -q -O- https://git.opnfv.org/functest/plain/upper-constraints.txt?h=$BRANCH | \
- sed -E /#egg=functest/d > upper-constraints.opnfv.txt && \
- git clone --depth 1 -b $VIMS_TEST_TAG https://github.com/Metaswitch/clearwater-live-test /src/vims-test && \
+ ruby-dev g++ make libxslt-dev libxml2-dev zlib-dev libffi-dev patch && \
+ git init /src/vims-test && \
+ (cd /src/vims-test && \
+ git fetch --tags https://github.com/Metaswitch/clearwater-live-test $VIMS_TEST_TAG && \
+ git checkout FETCH_HEAD) && \
sed -i s/unf_ext\ \(.*\)/unf_ext\ \(0.0.7.4\)/g /src/vims-test/Gemfile.lock && \
git init /src/vims-test/quaff && \
(cd /src/vims-test/quaff && \
@@ -43,10 +34,11 @@ RUN apk --no-cache add --update \
git init /src/heat_vims && \
(cd /src/heat_vims && \
git fetch --tags https://github.com/Metaswitch/clearwater-heat.git $HEAT_VIMS_TAG && \
- git checkout FETCH_HEAD) && \
+ git checkout FETCH_HEAD && \
+ patch -p1 < /tmp/clearwater-heat-singlenet-deps.patch) && \
git init /src/opnfv-vnf-vyos-blueprint && \
(cd /src/opnfv-vnf-vyos-blueprint && \
- git fetch --tags https://github.com/oolorg/opnfv-vnf-vyos-blueprint.git $VROUTER_TAG && \
+ git fetch --tags https://github.com/oolorg/opnfv-vnf-vyos-blueprint.git $VROUTER_BP_TAG && \
git checkout FETCH_HEAD) && \
mkdir -p /home/opnfv/functest/data/router && \
git init /home/opnfv/functest/data/router/opnfv-vnf-data && \
@@ -55,20 +47,12 @@ RUN apk --no-cache add --update \
git checkout FETCH_HEAD) && \
git init /src/epc-requirements/abot_charm && \
(cd /src/epc-requirements/abot_charm && \
- git fetch --tags https://github.com/RebacaInc/abot_charm.git $ABOT_CHARM && \
+ git fetch --tags https://github.com/collivier/abot_charm.git $ABOT_CHARM && \
git checkout FETCH_HEAD) && \
- python3 -m pip install --no-cache-dir --src /src -cupper-constraints.txt -cupper-constraints.opnfv.txt \
- juju-wait==$JUJU_WAIT_TAG && \
- go get -d github.com/rogpeppe/godeps && \
- (cd $GOPATH/src/github.com/rogpeppe/godeps && git checkout $GODEPS_TAG && go install -v github.com/rogpeppe/godeps) && \
- go get -d -v github.com/juju/juju/... || true && \
- (cd $GOPATH/src/github.com/juju/juju && git checkout $JUJU_TAG && godeps -u dependencies.tsv) && \
- go install -v github.com/juju/juju/... && \
- rm -r $GOPATH/src/ $GOPATH/pkg && \
- (cd /src/vims-test && bundle config build.nokogiri --use-system-libraries && bundle install --system) && \
- rm -r upper-constraints.txt upper-constraints.opnfv.txt /src/vims-test/.git /src/cloudify_vims/.git /src/heat_vims/.git /src/vims-test/quaff/.git \
+ (cd /src/vims-test && bundle config build.nokogiri --use-system-libraries && bundle install --system && bundle update rest-client) && \
+ rm -r /src/vims-test/.git /src/cloudify_vims/.git /src/heat_vims/.git /src/vims-test/quaff/.git \
/src/vims-test/build-infra/.git /src/opnfv-vnf-vyos-blueprint/.git \
- /src/epc-requirements/abot_charm/.git && \
+ /tmp/clearwater-heat-singlenet-deps.patch && \
apk del .build-deps
-COPY testcases.yaml /usr/lib/python2.7/site-packages/xtesting/ci/testcases.yaml
+COPY testcases.yaml /etc/xtesting/testcases.yaml
CMD ["run_tests", "-t", "all"]
diff --git a/docker/vnf/clearwater-heat-singlenet-deps.patch b/docker/vnf/clearwater-heat-singlenet-deps.patch
new file mode 100644
index 000000000..0e075f9f8
--- /dev/null
+++ b/docker/vnf/clearwater-heat-singlenet-deps.patch
@@ -0,0 +1,1849 @@
+diff --git a/bono.yaml b/bono.yaml
+index f0189cd..cc03838 100644
+--- a/bono.yaml
++++ b/bono.yaml
+@@ -23,26 +23,6 @@ parameters:
+ constraints:
+ - custom_constraint: neutron.network
+ description: Must be a valid network ID
+- public_sig_net_id:
+- type: string
+- description: ID of public signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_id:
+- type: string
+- description: ID of private signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_cidr:
+- type: string
+- description: Private signaling network address (CIDR notation)
+- default: 192.168.1.0/24
+- private_sig_net_gateway:
+- type: string
+- description: Private signaling network gateway address
+- default: 192.168.1.254
+ flavor:
+ type: string
+ description: Flavor to use
+@@ -64,9 +44,6 @@ parameters:
+ base_mgmt_security_group:
+ type: string
+ description: ID of base security group for all Clearwater nodes (managment)
+- bono_sig_security_group:
+- type: string
+- description: ID of security group for Bono nodes (signaling)
+ repo_url:
+ type: string
+ description: URL for Clearwater repository
+@@ -78,9 +55,6 @@ parameters:
+ dns_mgmt_ip:
+ type: string
+ description: IP address for DNS server on management network
+- dns_sig_ip:
+- type: string
+- description: IP address for DNS server on signaling network
+ dnssec_key:
+ type: string
+ description: DNSSEC private key (Base64-encoded)
+@@ -111,19 +85,15 @@ resources:
+ floating_network_id: { get_param: public_mgmt_net_id }
+ port_id: { get_resource: mgmt_port }
+
+- sig_port:
+- type: OS::Neutron::Port
++ wait_condition:
++ type: OS::Heat::WaitCondition
+ properties:
+- # Specify the network ID by string to work around OpenStack issues - see https://github.com/Metaswitch/clearwater-heat/issues/18.
+- network_id: { str_replace: { params: { x: { get_param: private_sig_net_id } }, template: x } }
+- security_groups:
+- - { get_param: bono_sig_security_group }
++ handle: {get_resource: wait_handle}
++ count: 1
++ timeout: 1200
+
+- sig_floating_ip:
+- type: OS::Neutron::FloatingIP
+- properties:
+- floating_network_id: { get_param: public_sig_net_id }
+- port_id: { get_resource: sig_port }
++ wait_handle:
++ type: OS::Heat::WaitConditionHandle
+
+ server:
+ type: OS::Nova::Server
+@@ -134,7 +104,6 @@ resources:
+ key_name: { get_param: key_name }
+ networks:
+ - port: { get_resource: mgmt_port }
+- - port: { get_resource: sig_port }
+ user_data_format: RAW
+ user_data:
+ str_replace:
+@@ -143,15 +112,11 @@ resources:
+ __zone__: { get_param: zone }
+ __public_mgmt_ip__: { get_attr: [ mgmt_floating_ip, floating_ip_address ] }
+ __private_mgmt_ip__: { get_attr: [ mgmt_port, fixed_ips, 0, ip_address ] }
+- __public_sig_ip__: { get_attr: [ sig_floating_ip, floating_ip_address ] }
+- __private_sig_ip__: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
+- __private_sig_cidr__: { get_param: private_sig_net_cidr }
+- __private_sig_gateway__: { get_param: private_sig_net_gateway }
+ __dns_mgmt_ip__: { get_param: dns_mgmt_ip }
+- __dns_sig_ip__: { get_param: dns_sig_ip }
+ __dnssec_key__: { get_param: dnssec_key }
+ __etcd_ip__ : { get_param: etcd_ip }
+ __index__ : { get_param: index }
++ wc_notify: { get_attr: [wait_handle, curl_cli] }
+ template: |
+ #!/bin/bash
+
+@@ -159,36 +124,8 @@ resources:
+ exec > >(tee -a /var/log/clearwater-heat-bono.log) 2>&1
+ set -x
+
+- # Set up the signaling network namespace on each boot by creating an init file and
+- # linking to it from runlevel 2 and 3
+- cat >/etc/init.d/signaling_namespace <<EOF
+- #!/bin/bash
+- # Create the signaling namespace and configure its interfaces.
+- set -e
+-
+- # Exit if the namespace is already set up.
+- ip netns list | grep -q signaling && exit 0
+-
+- # eth1 is the signaling interface (and eth0 is the management interface).
+- # We need to set eth1 up manually - only eth0 is automatically configured via DHCP.
+- ip netns add signaling
+- ip link set eth1 netns signaling
+- ip netns exec signaling ip link set dev lo up
+- ip netns exec signaling ip addr add __private_sig_ip__/$(echo __private_sig_cidr__ | cut -d / -f 2) dev eth1
+- ip netns exec signaling ip link set dev eth1 up
+- ip netns exec signaling ip route add default via __private_sig_gateway__
+- EOF
+-
+- chmod a+x /etc/init.d/signaling_namespace
+- ln -s /etc/init.d/signaling_namespace /etc/rc2.d/S01signaling_namespace
+- ln -s /etc/init.d/signaling_namespace /etc/rc3.d/S01signaling_namespace
+-
+- # Also set up the signaling namespace now.
+- /etc/init.d/signaling_namespace
+-
+ # Configure the APT software source.
+- echo 'deb __repo_url__ binary/' > /etc/apt/sources.list.d/clearwater.list
+- curl -L http://repo.cw-ngv.com/repo_key | apt-key add -
++ echo 'deb http://artifacts.opnfv.org/functest/clearwater/debian ./' > /etc/apt/sources.list.d/clearwater.list
+ apt-get update
+
+ # Configure /etc/clearwater/local_config.
+@@ -196,11 +133,8 @@ resources:
+ etcd_ip=__etcd_ip__
+ [ -n "$etcd_ip" ] || etcd_ip=__private_mgmt_ip__
+ cat > /etc/clearwater/local_config << EOF
+- signaling_namespace=signaling
+- signaling_dns_server=__dns_sig_ip__
+- management_local_ip=__private_mgmt_ip__
+- local_ip=__private_sig_ip__
+- public_ip=__public_sig_ip__
++ local_ip=__private_mgmt_ip__
++ public_ip=__public_mgmt_ip__
+ public_hostname=__index__.bono.__zone__
+ etcd_cluster=$etcd_ip
+ EOF
+@@ -223,8 +157,8 @@ resources:
+ while ! { nsupdate -y "__zone__:__dnssec_key__" -v << EOF
+ server __dns_mgmt_ip__
+ update add bono-__index__.__zone__. 30 $(ip2rr __public_mgmt_ip__)
+- update add __index__.bono.__zone__. 30 $(ip2rr __public_sig_ip__)
+- update add __zone__. 30 $(ip2rr __public_sig_ip__)
++ update add __index__.bono.__zone__. 30 $(ip2rr __public_mgmt_ip__)
++ update add __zone__. 30 $(ip2rr __public_mgmt_ip__)
+ update add __zone__. 30 NAPTR 0 0 "s" "SIP+D2T" "" _sip._tcp.__zone__.
+ update add __zone__. 30 NAPTR 0 0 "s" "SIP+D2U" "" _sip._udp.__zone__.
+ update add _sip._tcp.__zone__. 30 SRV 0 0 5060 __index__.bono.__zone__.
+@@ -241,10 +175,19 @@ resources:
+ # Use the DNS server.
+ echo 'nameserver __dns_mgmt_ip__' > /etc/dnsmasq.resolv.conf
+ echo 'RESOLV_CONF=/etc/dnsmasq.resolv.conf' >> /etc/default/dnsmasq
+- mkdir -p /etc/netns/signaling
+- echo 'nameserver __dns_sig_ip__' > /etc/netns/signaling/resolv.conf
+ service dnsmasq force-reload
+
++ for ((i=1;i<=10;i++)); do
++ monit summary
++ test -z "$(monit summary 2>&1 |sed '1,2d' |grep -v Running |grep -v Status\ ok )" && break || sleep 60
++ done
++ clearwater-etcdctl cluster-health
++ clearwater-etcdctl member list
++ cw-check_cluster_state
++ cw-check_config_sync
++
++ wc_notify --data-binary '{"status": "SUCCESS"}'
++
+ outputs:
+ public_mgmt_ip:
+ description: IP address in public management network
+@@ -252,9 +195,3 @@ outputs:
+ private_mgmt_ip:
+ description: IP address in private management network
+ value: { get_attr: [ mgmt_port, fixed_ips, 0, ip_address ] }
+- public_sig_ip:
+- description: IP address in public signaling network
+- value: { get_attr: [ sig_floating_ip, floating_ip_address ] }
+- private_sig_ip:
+- description: IP address in private signaling network
+- value: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
+diff --git a/clearwater.yaml b/clearwater.yaml
+index a155c60..dd90cb7 100644
+--- a/clearwater.yaml
++++ b/clearwater.yaml
+@@ -37,41 +37,6 @@ parameters:
+ type: string
+ description: IP address of external DNS server on management network
+ default: 8.8.8.8
+- public_sig_net_id:
+- type: string
+- description: ID of public signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_ip_version:
+- type: string
+- description: IP version (4 or 6) on the private signaling network
+- constraints:
+- - allowed_values:
+- - "4"
+- - "6"
+- description: Must be 4 (IPv4) or 6 (IPv6)
+- default: "4"
+- private_sig_net_cidr:
+- type: string
+- description: Private signaling network address (CIDR notation)
+- default: 192.168.1.0/24
+- private_sig_net_gateway:
+- type: string
+- description: Private signaling network gateway address
+- default: 192.168.1.254
+- private_sig_net_pool_start:
+- type: string
+- description: Start of private signaling network IP address pool
+- default: 192.168.1.1
+- private_sig_net_pool_end:
+- type: string
+- description: End of private signaling network IP address pool
+- default: 192.168.1.253
+- external_sig_dns_ip:
+- type: string
+- description: IP address of external DNS server on signaling network
+- default: 8.8.8.8
+ flavor:
+ type: string
+ description: Flavor to use
+@@ -151,18 +116,6 @@ resources:
+ private_net_pool_end: { get_param: private_mgmt_net_pool_end }
+ dns_ip: { get_param: external_mgmt_dns_ip }
+
+- sig_network:
+- type: ./network.yaml
+- properties:
+- public_net_id: { get_param: public_sig_net_id }
+- private_net_name: { str_replace: { params: { __stack__: { get_param: "OS::stack_name" } }, template: __stack__-private-signaling } }
+- private_net_ip_version: { get_param: private_sig_net_ip_version }
+- private_net_cidr: { get_param: private_sig_net_cidr }
+- private_net_gateway: { get_param: private_sig_net_gateway }
+- private_net_pool_start: { get_param: private_sig_net_pool_start }
+- private_net_pool_end: { get_param: private_sig_net_pool_end }
+- dns_ip: { get_param: external_sig_dns_ip }
+-
+ security_groups:
+ type: ./security-groups.yaml
+ properties:
+@@ -173,18 +126,17 @@ resources:
+ properties:
+ public_mgmt_net_id: { get_param: public_mgmt_net_id }
+ private_mgmt_net_id: { get_attr: [ mgmt_network, private_net ] }
+- public_sig_net_id: { get_param: public_sig_net_id }
+- private_sig_net_id: { get_attr: [ sig_network, private_net ] }
+- private_sig_net_cidr: { get_attr: [ sig_network, private_net_cidr ] }
+ flavor: { get_param: flavor }
+ image: { get_param: image }
+ key_name: { get_param: key_name }
+- dns_security_group: { get_attr: [ security_groups, dns ] }
++ base_mgmt_security_group: { get_attr: [ security_groups, base_mgmt ] }
+ zone: { get_param: zone }
+ dnssec_key: { get_param: dnssec_key }
++ dns_ip: { get_param: external_mgmt_dns_ip }
+
+ ellis:
+ type: ./ellis.yaml
++ depends_on: dns
+ properties:
+ public_mgmt_net_id: { get_param: public_mgmt_net_id }
+ private_mgmt_net_id: { get_attr: [ mgmt_network, private_net ] }
+@@ -192,7 +144,6 @@ resources:
+ image: { get_param: image }
+ key_name: { get_param: key_name }
+ base_mgmt_security_group: { get_attr: [ security_groups, base_mgmt ] }
+- ellis_mgmt_security_group: { get_attr: [ security_groups, ellis_mgmt ] }
+ repo_url: { get_param: repo_url }
+ zone: { get_param: zone }
+ dn_range_start: { get_param: dn_range_start }
+@@ -202,6 +153,7 @@ resources:
+
+ bono:
+ type: OS::Heat::ResourceGroup
++ depends_on: sprout
+ properties:
+ count: { get_param: bono_cluster_size }
+ index_var: "__index__"
+@@ -210,25 +162,20 @@ resources:
+ properties:
+ public_mgmt_net_id: { get_param: public_mgmt_net_id }
+ private_mgmt_net_id: { get_attr: [ mgmt_network, private_net ] }
+- public_sig_net_id: { get_param: public_sig_net_id }
+- private_sig_net_id: { get_attr: [ sig_network, private_net ] }
+- private_sig_net_cidr: { get_attr: [ sig_network, private_net_cidr ] }
+- private_sig_net_gateway: { get_attr: [ sig_network, private_net_gateway ] }
+ flavor: { get_param: flavor }
+ image: { get_param: image }
+ key_name: { get_param: key_name }
+ base_mgmt_security_group: { get_attr: [ security_groups, base_mgmt ] }
+- bono_sig_security_group: { get_attr: [ security_groups, bono_sig ] }
+ repo_url: { get_param: repo_url }
+ zone: { get_param: zone }
+ dns_mgmt_ip: { get_attr: [ dns, private_mgmt_ip ] }
+- dns_sig_ip: { get_attr: [ dns, private_sig_ip ] }
+ dnssec_key: { get_param: dnssec_key }
+ etcd_ip: { get_attr: [ ellis, private_mgmt_ip ] }
+ index: __index__
+
+ sprout:
+ type: OS::Heat::ResourceGroup
++ depends_on: vellum
+ properties:
+ count: { get_param: sprout_cluster_size }
+ index_var: __index__
+@@ -237,26 +184,20 @@ resources:
+ properties:
+ public_mgmt_net_id: { get_param: public_mgmt_net_id }
+ private_mgmt_net_id: { get_attr: [ mgmt_network, private_net ] }
+- public_sig_net_id: { get_param: public_sig_net_id }
+- private_sig_net_id: { get_attr: [ sig_network, private_net ] }
+- private_sig_net_cidr: { get_attr: [ sig_network, private_net_cidr ] }
+- private_sig_net_gateway: { get_attr: [ sig_network, private_net_gateway ] }
+ flavor: { get_param: flavor }
+ image: { get_param: image }
+ key_name: { get_param: key_name }
+ base_mgmt_security_group: { get_attr: [ security_groups, base_mgmt ] }
+- sprout_sig_outbound_security_group: { get_attr: [ security_groups, sprout_sig_outbound ] }
+- sprout_sig_inbound_security_group: { get_attr: [ security_groups, sprout_sig_inbound ] }
+ repo_url: { get_param: repo_url }
+ zone: { get_param: zone }
+ dns_mgmt_ip: { get_attr: [ dns, private_mgmt_ip ] }
+- dns_sig_ip: { get_attr: [ dns, private_sig_ip ] }
+ dnssec_key: { get_param: dnssec_key }
+ etcd_ip: { get_attr: [ ellis, private_mgmt_ip ] }
+ index: __index__
+
+ homer:
+ type: OS::Heat::ResourceGroup
++ depends_on: sprout
+ properties:
+ count: { get_param: homer_cluster_size }
+ index_var: __index__
+@@ -265,26 +206,20 @@ resources:
+ properties:
+ public_mgmt_net_id: { get_param: public_mgmt_net_id }
+ private_mgmt_net_id: { get_attr: [ mgmt_network, private_net ] }
+- public_sig_net_id: { get_param: public_sig_net_id }
+- private_sig_net_id: { get_attr: [ sig_network, private_net ] }
+- private_sig_net_cidr: { get_attr: [ sig_network, private_net_cidr ] }
+- private_sig_net_gateway: { get_attr: [ sig_network, private_net_gateway ] }
+ flavor: { get_param: flavor }
+ image: { get_param: image }
+ key_name: { get_param: key_name }
+ base_mgmt_security_group: { get_attr: [ security_groups, base_mgmt ] }
+- homer_mgmt_security_group: { get_attr: [ security_groups, homer_mgmt ] }
+- homer_sig_security_group: { get_attr: [ security_groups, homer_sig ] }
+ repo_url: { get_param: repo_url }
+ zone: { get_param: zone }
+ dns_mgmt_ip: { get_attr: [ dns, private_mgmt_ip ] }
+- dns_sig_ip: { get_attr: [ dns, private_sig_ip ] }
+ dnssec_key: { get_param: dnssec_key }
+ etcd_ip: { get_attr: [ ellis, private_mgmt_ip ] }
+ index: __index__
+
+ dime:
+ type: OS::Heat::ResourceGroup
++ depends_on: sprout
+ properties:
+ count: { get_param: dime_cluster_size }
+ index_var: __index__
+@@ -293,26 +228,20 @@ resources:
+ properties:
+ public_mgmt_net_id: { get_param: public_mgmt_net_id }
+ private_mgmt_net_id: { get_attr: [ mgmt_network, private_net ] }
+- public_sig_net_id: { get_param: public_sig_net_id }
+- private_sig_net_id: { get_attr: [ sig_network, private_net ] }
+- private_sig_net_cidr: { get_attr: [ sig_network, private_net_cidr ] }
+- private_sig_net_gateway: { get_attr: [ sig_network, private_net_gateway ] }
+ flavor: { get_param: flavor }
+ image: { get_param: image }
+ key_name: { get_param: key_name }
+ base_mgmt_security_group: { get_attr: [ security_groups, base_mgmt ] }
+- dime_mgmt_security_group: { get_attr: [ security_groups, dime_mgmt ] }
+- dime_sig_security_group: { get_attr: [ security_groups, dime_sig ] }
+ repo_url: { get_param: repo_url }
+ zone: { get_param: zone }
+ dns_mgmt_ip: { get_attr: [ dns, private_mgmt_ip ] }
+- dns_sig_ip: { get_attr: [ dns, private_sig_ip ] }
+ dnssec_key: { get_param: dnssec_key }
+ etcd_ip: { get_attr: [ ellis, private_mgmt_ip ] }
+ index: __index__
+
+ vellum:
+ type: OS::Heat::ResourceGroup
++ depends_on: ellis
+ properties:
+ count: { get_param: vellum_cluster_size }
+ index_var: __index__
+@@ -321,20 +250,13 @@ resources:
+ properties:
+ public_mgmt_net_id: { get_param: public_mgmt_net_id }
+ private_mgmt_net_id: { get_attr: [ mgmt_network, private_net ] }
+- public_sig_net_id: { get_param: public_sig_net_id }
+- private_sig_net_id: { get_attr: [ sig_network, private_net ] }
+- private_sig_net_cidr: { get_attr: [ sig_network, private_net_cidr ] }
+- private_sig_net_gateway: { get_attr: [ sig_network, private_net_gateway ] }
+ flavor: { get_param: flavor }
+ image: { get_param: image }
+ key_name: { get_param: key_name }
+ base_mgmt_security_group: { get_attr: [ security_groups, base_mgmt ] }
+- vellum_sig_outbound_security_group: { get_attr: [ security_groups, vellum_sig_outbound ] }
+- vellum_sig_inbound_security_group: { get_attr: [ security_groups, vellum_sig_inbound ] }
+ repo_url: { get_param: repo_url }
+ zone: { get_param: zone }
+ dns_mgmt_ip: { get_attr: [ dns, private_mgmt_ip ] }
+- dns_sig_ip: { get_attr: [ dns, private_sig_ip ] }
+ dnssec_key: { get_param: dnssec_key }
+ etcd_ip: { get_attr: [ ellis, private_mgmt_ip ] }
+ index: __index__
+diff --git a/dime.yaml b/dime.yaml
+index 642f19d..d2b8b92 100644
+--- a/dime.yaml
++++ b/dime.yaml
+@@ -23,26 +23,6 @@ parameters:
+ constraints:
+ - custom_constraint: neutron.network
+ description: Must be a valid network ID
+- public_sig_net_id:
+- type: string
+- description: ID of public signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_id:
+- type: string
+- description: ID of private signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_cidr:
+- type: string
+- description: Private signaling network address (CIDR notation)
+- default: 192.168.1.0/24
+- private_sig_net_gateway:
+- type: string
+- description: Private signaling network gateway address
+- default: 192.168.1.254
+ flavor:
+ type: string
+ description: Flavor to use
+@@ -64,12 +44,6 @@ parameters:
+ base_mgmt_security_group:
+ type: string
+ description: ID of base security group for all Clearwater nodes (management)
+- dime_sig_security_group:
+- type: string
+- description: ID of security group for Dime nodes (signaling)
+- dime_mgmt_security_group:
+- type: string
+- description: ID of security group for Dime nodes (management)
+ repo_url:
+ type: string
+ description: URL for Clearwater repository
+@@ -81,9 +55,6 @@ parameters:
+ dns_mgmt_ip:
+ type: string
+ description: IP address for DNS server on management network
+- dns_sig_ip:
+- type: string
+- description: IP address for DNS server on signaling network
+ dnssec_key:
+ type: string
+ description: DNSSEC private key (Base64-encoded)
+@@ -107,7 +78,6 @@ resources:
+ network_id: { str_replace: { params: { x: { get_param: private_mgmt_net_id } }, template: x } }
+ security_groups:
+ - { get_param: base_mgmt_security_group }
+- - { get_param: dime_mgmt_security_group }
+
+ mgmt_floating_ip:
+ type: OS::Neutron::FloatingIP
+@@ -115,13 +85,15 @@ resources:
+ floating_network_id: { get_param: public_mgmt_net_id }
+ port_id: { get_resource: mgmt_port }
+
+- sig_port:
+- type: OS::Neutron::Port
++ wait_condition:
++ type: OS::Heat::WaitCondition
+ properties:
+- # Specify the network ID by string to work around OpenStack issues - see https://github.com/Metaswitch/clearwater-heat/issues/18.
+- network_id: { str_replace: { params: { x: { get_param: private_sig_net_id } }, template: x } }
+- security_groups:
+- - { get_param: dime_sig_security_group }
++ handle: {get_resource: wait_handle}
++ count: 1
++ timeout: 1200
++
++ wait_handle:
++ type: OS::Heat::WaitConditionHandle
+
+ server:
+ type: OS::Nova::Server
+@@ -132,7 +104,6 @@ resources:
+ key_name: { get_param: key_name }
+ networks:
+ - port: { get_resource: mgmt_port }
+- - port: { get_resource: sig_port }
+ user_data_format: RAW
+ user_data:
+ str_replace:
+@@ -141,14 +112,11 @@ resources:
+ __zone__: { get_param: zone }
+ __public_mgmt_ip__: { get_attr: [ mgmt_floating_ip, floating_ip_address ] }
+ __private_mgmt_ip__: { get_attr: [ mgmt_port, fixed_ips, 0, ip_address ] }
+- __private_sig_ip__: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
+- __private_sig_cidr__: { get_param: private_sig_net_cidr }
+- __private_sig_gateway__: { get_param: private_sig_net_gateway }
+ __dns_mgmt_ip__: { get_param: dns_mgmt_ip }
+- __dns_sig_ip__: { get_param: dns_sig_ip }
+ __dnssec_key__: { get_param: dnssec_key }
+ __etcd_ip__ : { get_param: etcd_ip }
+ __index__ : { get_param: index }
++ wc_notify: { get_attr: [wait_handle, curl_cli] }
+ template: |
+ #!/bin/bash
+
+@@ -156,36 +124,8 @@ resources:
+ exec > >(tee -a /var/log/clearwater-heat-dime.log) 2>&1
+ set -x
+
+- # Set up the signaling network namespace on each boot by creating an init file and
+- # linking to it from runlevel 2 and 3
+- cat >/etc/init.d/signaling_namespace <<EOF
+- #!/bin/bash
+- # Create the signaling namespace and configure its interfaces.
+- set -e
+-
+- # Exit if the namespace is already set up.
+- ip netns list | grep -q signaling && exit 0
+-
+- # eth1 is the signaling interface (and eth0 is the management interface).
+- # We need to set eth1 up manually - only eth0 is automatically configured via DHCP.
+- ip netns add signaling
+- ip link set eth1 netns signaling
+- ip netns exec signaling ip link set dev lo up
+- ip netns exec signaling ip addr add __private_sig_ip__/$(echo __private_sig_cidr__ | cut -d / -f 2) dev eth1
+- ip netns exec signaling ip link set dev eth1 up
+- ip netns exec signaling ip route add default via __private_sig_gateway__
+- EOF
+-
+- chmod a+x /etc/init.d/signaling_namespace
+- ln -s /etc/init.d/signaling_namespace /etc/rc2.d/S01signaling_namespace
+- ln -s /etc/init.d/signaling_namespace /etc/rc3.d/S01signaling_namespace
+-
+- # Also set up the signaling namespace now.
+- /etc/init.d/signaling_namespace
+-
+ # Configure the APT software source.
+- echo 'deb __repo_url__ binary/' > /etc/apt/sources.list.d/clearwater.list
+- curl -L http://repo.cw-ngv.com/repo_key | apt-key add -
++ echo 'deb http://artifacts.opnfv.org/functest/clearwater/debian ./' > /etc/apt/sources.list.d/clearwater.list
+ apt-get update
+
+ # Configure /etc/clearwater/local_config.
+@@ -193,11 +133,8 @@ resources:
+ etcd_ip=__etcd_ip__
+ [ -n "$etcd_ip" ] || etcd_ip=__private_mgmt_ip__
+ cat > /etc/clearwater/local_config << EOF
+- signaling_namespace=signaling
+- signaling_dns_server=__dns_sig_ip__
+- management_local_ip=__private_mgmt_ip__
+- local_ip=__private_sig_ip__
+- public_ip=__private_sig_ip__
++ local_ip=__private_mgmt_ip__
++ public_ip=__private_mgmt_ip__
+ public_hostname=dime-__index__.__zone__
+ etcd_cluster=$etcd_ip
+ EOF
+@@ -220,9 +157,9 @@ resources:
+ while ! { nsupdate -y "__zone__:__dnssec_key__" -v << EOF
+ server __dns_mgmt_ip__
+ update add dime-__index__.__zone__. 30 $(ip2rr __public_mgmt_ip__)
+- update add ralf.__zone__. 30 $(ip2rr __private_sig_ip__)
+- update add hs.__zone__. 30 $(ip2rr __private_sig_ip__)
+- update add hs-prov.__zone__. 30 $(ip2rr __private_mgmt_ip__)
++ update add ralf.__zone__. 30 $(ip2rr __public_mgmt_ip__)
++ update add hs.__zone__. 30 $(ip2rr __public_mgmt_ip__)
++ update add hs-prov.__zone__. 30 $(ip2rr __public_mgmt_ip__)
+ send
+ EOF
+ } && [ $retries -lt 10 ]
+@@ -235,17 +172,22 @@ resources:
+ # Use the DNS server.
+ echo 'nameserver __dns_mgmt_ip__' > /etc/dnsmasq.resolv.conf
+ echo 'RESOLV_CONF=/etc/dnsmasq.resolv.conf' >> /etc/default/dnsmasq
+- mkdir -p /etc/netns/signaling
+- echo 'nameserver __dns_sig_ip__' > /etc/netns/signaling/resolv.conf
+ service dnsmasq force-reload
+
++ for ((i=1;i<=10;i++)); do
++ monit summary
++ test -z "$(monit summary 2>&1 |sed '1,2d' |grep -v Running |grep -v Status\ ok )" && break || sleep 60
++ done
++ clearwater-etcdctl cluster-health
++ clearwater-etcdctl member list
++ cw-check_config_sync
++
++ wc_notify --data-binary '{"status": "SUCCESS"}'
++
+ outputs:
+ public_mgmt_ip:
+ description: IP address in public (management) network
+ value: { get_attr: [ mgmt_floating_ip, floating_ip_address ] }
+ private_mgmt_ip:
+- description: IP address in private signaling network
++ description: IP address in private management network
+ value: { get_attr: [ mgmt_port, fixed_ips, 0, ip_address ] }
+- private_sig_ip:
+- description: IP address in private signaling network
+- value: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
+diff --git a/dns.yaml b/dns.yaml
+index 825ede1..f98ffa3 100644
+--- a/dns.yaml
++++ b/dns.yaml
+@@ -23,22 +23,6 @@ parameters:
+ constraints:
+ - custom_constraint: neutron.network
+ description: Must be a valid network ID
+- public_sig_net_id:
+- type: string
+- description: ID of public signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_id:
+- type: string
+- description: ID of private signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_cidr:
+- type: string
+- description: Private signaling network address (CIDR notation)
+- default: 192.168.1.0/24
+ flavor:
+ type: string
+ description: Flavor to use
+@@ -57,7 +41,7 @@ parameters:
+ constraints:
+ - custom_constraint: nova.keypair
+ description: Must be a valid keypair name
+- dns_security_group:
++ base_mgmt_security_group:
+ type: string
+ description: ID of security group for DNS nodes
+ zone:
+@@ -67,6 +51,10 @@ parameters:
+ dnssec_key:
+ type: string
+ description: DNSSEC private key (Base64-encoded)
++ dns_ip:
++ type: string
++ description: IP address of DNS server
++ default: 8.8.8.8
+
+ resources:
+ mgmt_port:
+@@ -75,7 +63,7 @@ resources:
+ # Specify the network ID by string to work around OpenStack issues - see https://github.com/Metaswitch/clearwater-heat/issues/18.
+ network_id: { str_replace: { params: { x: { get_param: private_mgmt_net_id } }, template: x } }
+ security_groups:
+- - { get_param: dns_security_group }
++ - { get_param: base_mgmt_security_group }
+
+ mgmt_floating_ip:
+ type: OS::Neutron::FloatingIP
+@@ -83,13 +71,15 @@ resources:
+ floating_network_id: { get_param: public_mgmt_net_id }
+ port_id: { get_resource: mgmt_port }
+
+- sig_port:
+- type: OS::Neutron::Port
++ wait_condition:
++ type: OS::Heat::WaitCondition
+ properties:
+- # Specify the network ID by string to work around OpenStack issues - see https://github.com/Metaswitch/clearwater-heat/issues/18.
+- network_id: { str_replace: { params: { x: { get_param: private_sig_net_id } }, template: x } }
+- security_groups:
+- - { get_param: dns_security_group }
++ handle: {get_resource: wait_handle}
++ count: 1
++ timeout: 1200
++
++ wait_handle:
++ type: OS::Heat::WaitConditionHandle
+
+ server:
+ type: OS::Nova::Server
+@@ -100,16 +90,15 @@ resources:
+ key_name: { get_param: key_name }
+ networks:
+ - port: { get_resource: mgmt_port }
+- - port: { get_resource: sig_port }
+ user_data_format: RAW
+ user_data:
+ str_replace:
+ params:
+ __zone__: { get_param: zone }
+ __dnssec_key__: { get_param: dnssec_key }
++ __dns_ip__: { get_param: dns_ip }
+ __public_ip__: { get_attr: [ mgmt_floating_ip, floating_ip_address ] }
+- __private_sig_ip__: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
+- __private_sig_cidr__: { get_param: private_sig_net_cidr }
++ wc_notify: { get_attr: [wait_handle, curl_cli] }
+ template: |
+ #!/bin/bash
+
+@@ -117,14 +106,22 @@ resources:
+ exec > >(tee -a /var/log/clearwater-heat-dns.log) 2>&1
+ set -x
+
+- # Set up the signaling network interface
+- ip addr add __private_sig_ip__/$(echo __private_sig_cidr__ | cut -d / -f 2) dev eth1
+- ip link set dev eth1 up
+-
+ # Install BIND.
+ apt-get update
+ DEBIAN_FRONTEND=noninteractive apt-get install bind9 --yes
+
++ cat > /etc/bind/named.conf.options << EOF
++ options {
++ directory "/var/cache/bind";
++ forwarders {
++ __dns_ip__;
++ };
++ dnssec-validation auto;
++ auth-nxdomain no;
++ listen-on-v6 { any; };
++ };
++ EOF
++
+ # Update BIND configuration with the specified zone and key.
+ cat >> /etc/bind/named.conf.local << EOF
+ key __zone__. {
+@@ -163,6 +160,8 @@ resources:
+ # Now that BIND configuration is correct, kick it to reload.
+ service bind9 reload
+
++ wc_notify --data-binary '{"status": "SUCCESS"}'
++
+ outputs:
+ public_mgmt_ip:
+ description: IP address in public management network
+@@ -170,9 +169,6 @@ outputs:
+ private_mgmt_ip:
+ description: IP address in private signaling network
+ value: { get_attr: [ mgmt_port, fixed_ips, 0, ip_address ] }
+- private_sig_ip:
+- description: IP address in private signaling network
+- value: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
+ zone:
+ description: DNS zone
+ value: { get_param: zone }
+diff --git a/ellis.yaml b/ellis.yaml
+index 963352d..2bd0730 100644
+--- a/ellis.yaml
++++ b/ellis.yaml
+@@ -44,9 +44,6 @@ parameters:
+ base_mgmt_security_group:
+ type: string
+ description: ID of base security group for all Clearwater nodes (management)
+- ellis_mgmt_security_group:
+- type: string
+- description: ID of security group for Ellis nodes (management)
+ repo_url:
+ type: string
+ description: URL for Clearwater repository
+@@ -95,7 +92,6 @@ resources:
+ network_id: { str_replace: { params: { x: { get_param: private_mgmt_net_id } }, template: x } }
+ security_groups:
+ - { get_param: base_mgmt_security_group }
+- - { get_param: ellis_mgmt_security_group }
+
+ mgmt_floating_ip:
+ type: OS::Neutron::FloatingIP
+@@ -103,6 +99,16 @@ resources:
+ floating_network_id: { get_param: public_mgmt_net_id }
+ port_id: { get_resource: mgmt_port }
+
++ wait_condition:
++ type: OS::Heat::WaitCondition
++ properties:
++ handle: {get_resource: wait_handle}
++ count: 1
++ timeout: 1200
++
++ wait_handle:
++ type: OS::Heat::WaitConditionHandle
++
+ server:
+ type: OS::Nova::Server
+ properties:
+@@ -126,6 +132,7 @@ resources:
+ __dnssec_key__: { get_param: dnssec_key }
+ __etcd_ip__ : { get_param: etcd_ip }
+ __index__ : { get_param: index }
++ wc_notify: { get_attr: [wait_handle, curl_cli] }
+ template: |
+ #!/bin/bash
+
+@@ -134,8 +141,7 @@ resources:
+ set -x
+
+ # Configure the APT software source.
+- echo 'deb __repo_url__ binary/' > /etc/apt/sources.list.d/clearwater.list
+- curl -L http://repo.cw-ngv.com/repo_key | apt-key add -
++ echo 'deb http://artifacts.opnfv.org/functest/clearwater/debian ./' > /etc/apt/sources.list.d/clearwater.list
+ apt-get update
+
+ # Configure /etc/clearwater/local_config. Add xdms_hostname here to use Homer's management
+@@ -176,7 +182,7 @@ resources:
+ chronos_hostname=vellum.__zone__
+ ralf_session_store=vellum.__zone__
+
+- upstream_port=0
++ upstream_hostname=sprout.__zone__
+
+ # Email server configuration
+ smtp_smarthost=localhost
+@@ -189,6 +195,8 @@ resources:
+ turn_workaround=secret
+ ellis_api_key=secret
+ ellis_cookie_key=secret
++
++ reduce_cassandra_mem_usage=Y
+ EOF
+ /usr/share/clearwater/clearwater-config-manager/scripts/cw-config upload shared_config --autoconfirm --dir /tmp
+
+@@ -197,7 +205,6 @@ resources:
+ # local_settings.py runs to pick up the configuration changes.
+ service clearwater-infrastructure restart
+ service ellis stop
+- /usr/share/clearwater/ellis/env/bin/python /usr/share/clearwater/ellis/src/metaswitch/ellis/tools/create_numbers.py --start __dn_range_start__ --count __dn_range_length__ --realm __zone__
+
+ # Function to give DNS record type and IP address for specified IP address
+ ip2rr() {
+@@ -228,6 +235,18 @@ resources:
+ echo 'RESOLV_CONF=/etc/dnsmasq.resolv.conf' >> /etc/default/dnsmasq
+ service dnsmasq force-reload
+
++ for ((i=1;i<=10;i++)); do
++ monit summary
++ test -z "$(monit summary 2>&1 |sed '1,2d' |grep -v Running |grep -v Status\ ok )" && break || sleep 60
++ done
++ clearwater-etcdctl cluster-health
++ clearwater-etcdctl member list
++ cw-check_config_sync
++
++ /usr/share/clearwater/ellis/env/bin/python /usr/share/clearwater/ellis/src/metaswitch/ellis/tools/create_numbers.py --start __dn_range_start__ --count __dn_range_length__ --realm __zone__
++
++ wc_notify --data-binary '{"status": "SUCCESS"}'
++
+ outputs:
+ public_mgmt_ip:
+ description: IP address in public management network
+diff --git a/homer.yaml b/homer.yaml
+index 4337984..d23adb5 100644
+--- a/homer.yaml
++++ b/homer.yaml
+@@ -23,26 +23,6 @@ parameters:
+ constraints:
+ - custom_constraint: neutron.network
+ description: Must be a valid network ID
+- public_sig_net_id:
+- type: string
+- description: ID of public signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_id:
+- type: string
+- description: ID of private signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_cidr:
+- type: string
+- description: Private signaling network address (CIDR notation)
+- default: 192.168.1.0/24
+- private_sig_net_gateway:
+- type: string
+- description: Private signaling network gateway address
+- default: 192.168.1.254
+ flavor:
+ type: string
+ description: Flavor to use
+@@ -64,12 +44,6 @@ parameters:
+ base_mgmt_security_group:
+ type: string
+ description: ID of base security group for all Clearwater nodes (management)
+- homer_mgmt_security_group:
+- type: string
+- description: ID of security group for Homer nodes (maangement)
+- homer_sig_security_group:
+- type: string
+- description: ID of security group for Homer nodes (signaling)
+ repo_url:
+ type: string
+ description: URL for Clearwater repository
+@@ -81,9 +55,6 @@ parameters:
+ dns_mgmt_ip:
+ type: string
+ description: IP address for DNS server on management network
+- dns_sig_ip:
+- type: string
+- description: IP address for DNS server on signaling network
+ dnssec_key:
+ type: string
+ description: DNSSEC private key (Base64-encoded)
+@@ -107,7 +78,6 @@ resources:
+ network_id: { str_replace: { params: { x: { get_param: private_mgmt_net_id } }, template: x } }
+ security_groups:
+ - { get_param: base_mgmt_security_group }
+- - { get_param: homer_mgmt_security_group }
+
+ mgmt_floating_ip:
+ type: OS::Neutron::FloatingIP
+@@ -115,19 +85,15 @@ resources:
+ floating_network_id: { get_param: public_mgmt_net_id }
+ port_id: { get_resource: mgmt_port }
+
+- sig_port:
+- type: OS::Neutron::Port
++ wait_condition:
++ type: OS::Heat::WaitCondition
+ properties:
+- # Specify the network ID by string to work around OpenStack issues - see https://github.com/Metaswitch/clearwater-heat/issues/18.
+- network_id: { str_replace: { params: { x: { get_param: private_sig_net_id } }, template: x } }
+- security_groups:
+- - { get_param: homer_sig_security_group }
++ handle: {get_resource: wait_handle}
++ count: 1
++ timeout: 1200
+
+- sig_floating_ip:
+- type: OS::Neutron::FloatingIP
+- properties:
+- floating_network_id: { get_param: public_sig_net_id }
+- port_id: { get_resource: sig_port }
++ wait_handle:
++ type: OS::Heat::WaitConditionHandle
+
+ server:
+ type: OS::Nova::Server
+@@ -138,7 +104,6 @@ resources:
+ key_name: { get_param: key_name }
+ networks:
+ - port: { get_resource: mgmt_port }
+- - port: { get_resource: sig_port }
+ user_data_format: RAW
+ user_data:
+ str_replace:
+@@ -147,15 +112,11 @@ resources:
+ __zone__: { get_param: zone }
+ __public_mgmt_ip__: { get_attr: [ mgmt_floating_ip, floating_ip_address ] }
+ __private_mgmt_ip__: { get_attr: [ mgmt_port, fixed_ips, 0, ip_address ] }
+- __public_sig_ip__: { get_attr: [ sig_floating_ip, floating_ip_address ] }
+- __private_sig_ip__: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
+- __private_sig_cidr__: { get_param: private_sig_net_cidr }
+- __private_sig_gateway__: { get_param: private_sig_net_gateway }
+ __dns_mgmt_ip__: { get_param: dns_mgmt_ip }
+- __dns_sig_ip__: { get_param: dns_sig_ip }
+ __dnssec_key__: { get_param: dnssec_key }
+ __etcd_ip__ : { get_param: etcd_ip }
+ __index__ : { get_param: index }
++ wc_notify: { get_attr: [wait_handle, curl_cli] }
+ template: |
+ #!/bin/bash
+
+@@ -163,36 +124,8 @@ resources:
+ exec > >(tee -a /var/log/clearwater-heat-homer.log) 2>&1
+ set -x
+
+- # Set up the signaling network namespace on each boot by creating an init file and
+- # linking to it from runlevel 2 and 3
+- cat >/etc/init.d/signaling_namespace <<EOF
+- #!/bin/bash
+- # Create the signaling namespace and configure its interfaces.
+- set -e
+-
+- # Exit if the namespace is already set up.
+- ip netns list | grep -q signaling && exit 0
+-
+- # eth1 is the signaling interface (and eth0 is the management interface).
+- # We need to set eth1 up manually - only eth0 is automatically configured via DHCP.
+- ip netns add signaling
+- ip link set eth1 netns signaling
+- ip netns exec signaling ip link set dev lo up
+- ip netns exec signaling ip addr add __private_sig_ip__/$(echo __private_sig_cidr__ | cut -d / -f 2) dev eth1
+- ip netns exec signaling ip link set dev eth1 up
+- ip netns exec signaling ip route add default via __private_sig_gateway__
+- EOF
+-
+- chmod a+x /etc/init.d/signaling_namespace
+- ln -s /etc/init.d/signaling_namespace /etc/rc2.d/S01signaling_namespace
+- ln -s /etc/init.d/signaling_namespace /etc/rc3.d/S01signaling_namespace
+-
+- # Also set up the signaling namespace now.
+- /etc/init.d/signaling_namespace
+-
+ # Configure the APT software source.
+- echo 'deb __repo_url__ binary/' > /etc/apt/sources.list.d/clearwater.list
+- curl -L http://repo.cw-ngv.com/repo_key | apt-key add -
++ echo 'deb http://artifacts.opnfv.org/functest/clearwater/debian ./' > /etc/apt/sources.list.d/clearwater.list
+ apt-get update
+
+ # Configure /etc/clearwater/local_config.
+@@ -200,11 +133,8 @@ resources:
+ etcd_ip=__etcd_ip__
+ [ -n "$etcd_ip" ] || etcd_ip=__private_mgmt_ip__
+ cat > /etc/clearwater/local_config << EOF
+- signaling_namespace=signaling
+- signaling_dns_server=__dns_sig_ip__
+- management_local_ip=__private_mgmt_ip__
+- local_ip=__private_sig_ip__
+- public_ip=__public_sig_ip__
++ local_ip=__private_mgmt_ip__
++ public_ip=__public_mgmt_ip__
+ public_hostname=homer-__index__.__zone__
+ etcd_cluster=$etcd_ip
+ EOF
+@@ -227,7 +157,7 @@ resources:
+ while ! { nsupdate -y "__zone__:__dnssec_key__" -v << EOF
+ server __dns_mgmt_ip__
+ update add homer-__index__.__zone__. 30 $(ip2rr __public_mgmt_ip__)
+- update add homer.__zone__. 30 $(ip2rr __public_sig_ip__)
++ update add homer.__zone__. 30 $(ip2rr __public_mgmt_ip__)
+ send
+ EOF
+ } && [ $retries -lt 10 ]
+@@ -237,14 +167,22 @@ resources:
+ sleep 5
+ done
+
+- # Use the DNS server.
+ # Use the DNS server.
+ echo 'nameserver __dns_mgmt_ip__' > /etc/dnsmasq.resolv.conf
+ echo 'RESOLV_CONF=/etc/dnsmasq.resolv.conf' >> /etc/default/dnsmasq
+- mkdir -p /etc/netns/signaling
+- echo 'nameserver __dns_sig_ip__' > /etc/netns/signaling/resolv.conf
+ service dnsmasq force-reload
+
++ for ((i=1;i<=10;i++)); do
++ monit summary
++ test -z "$(monit summary 2>&1 |sed '1,2d' |grep -v Running |grep -v Status\ ok )" && break || sleep 60
++ done
++ clearwater-etcdctl cluster-health
++ clearwater-etcdctl member list
++ cw-check_cluster_state
++ cw-check_config_sync
++
++ wc_notify --data-binary '{"status": "SUCCESS"}'
++
+ outputs:
+ public_mgmt_ip:
+ description: IP address in public management network
+@@ -252,9 +190,3 @@ outputs:
+ private_mgmt_ip:
+ description: IP address in private management network
+ value: { get_attr: [ mgmt_port, fixed_ips, 0, ip_address ] }
+- public_sig_ip:
+- description: IP address in public signaling network
+- value: { get_attr: [ sig_floating_ip, floating_ip_address ] }
+- private_sig_ip:
+- description: IP address in private signaling network
+- value: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
+diff --git a/security-groups.yaml b/security-groups.yaml
+index 5921d32..c73fe2b 100644
+--- a/security-groups.yaml
++++ b/security-groups.yaml
+@@ -32,340 +32,14 @@ resources:
+ - protocol: icmp
+ # SSH
+ - protocol: tcp
+- port_range_min: 22
+- port_range_max: 22
++ port_range_min: 1
++ port_range_max: 65535
+ # SNMP
+ - protocol: udp
+- port_range_min: 161
+- port_range_max: 161
+- # etcd
+- - protocol: tcp
+- port_range_min: 2380
+- port_range_max: 2380
+- remote_mode: remote_group_id
+- #remote_group_id: { get_resource: base_mgmt } # omit remote_group_id to reference yourself
+- - protocol: tcp
+- port_range_min: 4000
+- port_range_max: 4000
+- remote_mode: remote_group_id
+- #remote_group_id: { get_resource: base_mgmt } # omit remote_group_id to reference yourself
+-
+- dns:
+- type: OS::Neutron::SecurityGroup
+- properties:
+- name: { str_replace: { params: { __name_prefix__: { get_param: "name_prefix" } }, template: __name_prefix__-dns } }
+- description: Security group for DNS nodes
+- rules:
+- # All egress traffic
+- - direction: egress
+- ethertype: IPv4
+- - direction: egress
+- ethertype: IPv6
+- # ICMP
+- - protocol: icmp
+- # SSH
+- - protocol: tcp
+- port_range_min: 22
+- port_range_max: 22
+- # DNS
+- - protocol: udp
+- port_range_min: 53
+- port_range_max: 53
+- - protocol: tcp
+- port_range_min: 53
+- port_range_max: 53
+-
+- ellis_mgmt:
+- type: OS::Neutron::SecurityGroup
+- properties:
+- name: { str_replace: { params: { __name_prefix__: { get_param: "name_prefix" } }, template: __name_prefix__-ellis-mgmt } }
+- description: Security group for Ellis nodes (management)
+- rules:
+- # HTTP
+- - protocol: tcp
+- port_range_min: 80
+- port_range_max: 80
+- # HTTPS
+- - protocol: tcp
+- port_range_min: 443
+- port_range_max: 443
+-
+- bono_sig:
+- type: OS::Neutron::SecurityGroup
+- properties:
+- name: { str_replace: { params: { __name_prefix__: { get_param: "name_prefix" } }, template: __name_prefix__-bono-sig } }
+- description: Security group for Bono nodes (signaling)
+- rules:
+- # STUN/TURN
+- - protocol: udp
+- port_range_min: 3478
+- port_range_max: 3478
+- - protocol: tcp
+- port_range_min: 3478
+- port_range_max: 3478
+- # Internal SIP
+- - protocol: tcp
+- port_range_min: 5058
+- port_range_max: 5058
+- remote_mode: remote_group_id
+- #remote_group_id: { get_resource: bono_sig } # omit remote_group_id to reference yourself
+- - protocol: tcp
+- port_range_min: 5058
+- port_range_max: 5058
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: sprout_sig_outbound }
+- # External SIP
+- - protocol: udp
+- port_range_min: 5060
+- port_range_max: 5060
+- - protocol: tcp
+- port_range_min: 5060
+- port_range_max: 5060
+- # External SIP/WebSocket
+- - protocol: tcp
+- port_range_min: 5062
+- port_range_max: 5062
+- # RTP
+- - protocol: udp
+- port_range_min: 32768
++ port_range_min: 1
+ port_range_max: 65535
+
+-
+- sprout_sig_outbound:
+- type: OS::Neutron::SecurityGroup
+- properties:
+- name: { str_replace: { params: { __name_prefix__: { get_param: "name_prefix" } }, template: __name_prefix__-sprout-sig-outbound } }
+- description: Security group for Sprout nodes outbound traffic (signaling)
+- rules:
+- # Internal SIP
+- - protocol: tcp
+- port_range_min: 5052
+- port_range_max: 5052
+- remote_mode: remote_group_id
+- #remote_group_id: { get_resource: sprout_sig_outbound } # omit remote_group_id to reference yourself
+- - protocol: tcp
+- port_range_min: 5054
+- port_range_max: 5054
+- remote_mode: remote_group_id
+- #remote_group_id: { get_resource: sprout_sig_outbound } # omit remote_group_id to reference yourself
+-
+- sprout_sig_inbound:
+- type: OS::Neutron::SecurityGroup
+- properties:
+- name: { str_replace: { params: { __name_prefix__: { get_param: "name_prefix" } }, template: __name_prefix__-sprout-sig-inbound } }
+- description: Security group for Sprout nodes inbound traffic (signaling)
+- rules:
+- # Internal SIP
+- - protocol: tcp
+- port_range_min: 5052
+- port_range_max: 5052
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: bono_sig }
+- - protocol: tcp
+- port_range_min: 5054
+- port_range_max: 5054
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: bono_sig }
+- # Chronos timer pops
+- - protocol: tcp
+- port_range_min: 9888
+- port_range_max: 9888
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: vellum_sig_outbound }
+- # Notifications from Homestead
+- - protocol: tcp
+- port_range_min: 9888
+- port_range_max: 9888
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: dime_sig }
+-
+- homer_mgmt:
+- type: OS::Neutron::SecurityGroup
+- properties:
+- name: { str_replace: { params: { __name_prefix__: { get_param: "name_prefix" } }, template: __name_prefix__-homer-mgmt } }
+- description: Security group for Homer nodes (management)
+- rules:
+- # Ut/HTTP
+- - protocol: tcp
+- port_range_min: 7888
+- port_range_max: 7888
+- - protocol: tcp
+- port_range_min: 7888
+- port_range_max: 7888
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: sprout_sig_outbound }
+-
+- homer_sig:
+- type: OS::Neutron::SecurityGroup
+- properties:
+- name: { str_replace: { params: { __name_prefix__: { get_param: "name_prefix" } }, template: __name_prefix__-homer-sig } }
+- description: Security group for Homer nodes (signaling)
+- rules:
+- # Ut/HTTP
+- - protocol: tcp
+- port_range_min: 7888
+- port_range_max: 7888
+- - protocol: tcp
+- port_range_min: 7888
+- port_range_max: 7888
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: sprout_sig_outbound }
+- - protocol: tcp
+- port_range_min: 9160
+- port_range_max: 9160
+- remote_mode: remote_group_id
+- #remote_group_id: { get_resource: homer_sig } # omit remote_group_id to reference yourself
+-
+- dime_mgmt:
+- type: OS::Neutron::SecurityGroup
+- properties:
+- name: { str_replace: { params: { __name_prefix__: { get_param: "name_prefix" } }, template: __name_prefix__-dime-mgmt } }
+- description: Security group for Dime nodes (management)
+- rules:
+- # REST-ful Provisioning API
+- - protocol: tcp
+- port_range_min: 8889
+- port_range_max: 8889
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: ellis_mgmt }
+-
+- dime_sig:
+- type: OS::Neutron::SecurityGroup
+- properties:
+- name: { str_replace: { params: { __name_prefix__: { get_param: "name_prefix" } }, template: __name_prefix__-dime-sig } }
+- description: Security group for Dime nodes (signaling)
+- rules:
+- # Cx-like HTTP API
+- - protocol: tcp
+- port_range_min: 8888
+- port_range_max: 8888
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: bono_sig }
+- - protocol: tcp
+- port_range_min: 8888
+- port_range_max: 8888
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: sprout_sig_outbound }
+- # Rf-like/HTTP API
+- - protocol: tcp
+- port_range_min: 10888
+- port_range_max: 10888
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: bono_sig }
+- - protocol: tcp
+- port_range_min: 10888
+- port_range_max: 10888
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: sprout_sig_outbound }
+- # Chronos timer pops
+- - protocol: tcp
+- port_range_min: 10888
+- port_range_max: 10888
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: vellum_sig_outbound }
+-
+- vellum_sig_outbound:
+- type: OS::Neutron::SecurityGroup
+- properties:
+- name: { str_replace: { params: { __name_prefix__: { get_param: "name_prefix" } }, template: __name_prefix__-vellum-sig-outbound } }
+- description: Security group for Vellum nodes outbound traffic (signaling)
+- rules:
+- # Chronos
+- - protocol: tcp
+- port_range_min: 7253
+- port_range_max: 7253
+- remote_mode: remote_group_id
+- #remote_group_id: { get_resource: vellum_sig_outbound } # omit remote_group_id to reference yourself
+- # Cassandra
+- - protocol: tcp
+- port_range_min: 7000
+- port_range_max: 7000
+- remote_mode: remote_group_id
+- #remote_group_id: { get_resource: vellum_sig_outbound } # omit remote_group_id to reference yourself
+- # Memcached listening to Astaire
+- - protocol: tcp
+- port_range_min: 11211
+- port_range_max: 11211
+- remote_mode: remote_group_id
+- #remote_group_id: { get_resource: vellum_sig_outbound } # omit remote_group_id to reference yourself
+-
+- vellum_sig_inbound:
+- type: OS::Neutron::SecurityGroup
+- properties:
+- name: { str_replace: { params: { __name_prefix__: { get_param: "name_prefix" } }, template: __name_prefix__-vellum-sig-inbound } }
+- description: Security group for Vellum nodes inbound traffic (signaling)
+- rules:
+- # Astaire
+- - protocol: tcp
+- port_range_min: 11311
+- port_range_max: 11311
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: sprout_sig_outbound }
+- # Astaire
+- - protocol: tcp
+- port_range_min: 11311
+- port_range_max: 11311
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: dime_sig }
+- # Chronos
+- - protocol: tcp
+- port_range_min: 7253
+- port_range_max: 7253
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: sprout_sig_outbound }
+- # Chronos
+- - protocol: tcp
+- port_range_min: 7253
+- port_range_max: 7253
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: dime_sig }
+- # Cassandra Thrift
+- - protocol: tcp
+- port_range_min: 9160
+- port_range_max: 9160
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: dime_sig }
+- # Cassandra Thrift
+- - protocol: tcp
+- port_range_min: 9160
+- port_range_max: 9160
+- remote_mode: remote_group_id
+- remote_group_id: { get_resource: homer_sig }
+-
+ outputs:
+ base_mgmt:
+ description: Base security group for all Clearwater nodes (management)
+- value: { get_resource: base_mgmt }
+- dns:
+- description: Security group for DNS nodes
+- value: { get_resource: dns }
+- ellis_mgmt:
+- description: Security group for Ellis nodes (managment)
+- value: { get_resource: ellis_mgmt }
+- bono_sig:
+- description: Security group for Bono nodes (signaling)
+- value: { get_resource: bono_sig }
+- sprout_sig_outbound:
+- description: Security group for Sprout nodes outbound traffic (signaling)
+- value: { get_resource: sprout_sig_outbound }
+- sprout_sig_inbound:
+- description: Security group for Sprout nodes inbound traffic (signaling)
+- value: { get_resource: sprout_sig_inbound }
+- homer_mgmt:
+- description: Security group for Homer nodes (management)
+- value: { get_resource: homer_mgmt }
+- homer_sig:
+- description: Security group for Homer nodes (signaling)
+- value: { get_resource: homer_sig }
+- dime_mgmt:
+- description: Security group for Dime nodes (management)
+- value: { get_resource: dime_mgmt }
+- dime_sig:
+- description: Security group for Dime nodes (signaling)
+- value: { get_resource: dime_sig }
+- vellum_sig_outbound:
+- description: Security group for Vellum nodes outbound traffic (signaling)
+- value: { get_resource: vellum_sig_outbound }
+- vellum_sig_inbound:
+- description: Security group for Vellum nodes inbound traffic (signaling)
+- value: { get_resource: vellum_sig_inbound }
++ value: { get_resource: base_mgmt }
+diff --git a/sprout.yaml b/sprout.yaml
+index 9c533b7..b51750b 100644
+--- a/sprout.yaml
++++ b/sprout.yaml
+@@ -23,26 +23,6 @@ parameters:
+ constraints:
+ - custom_constraint: neutron.network
+ description: Must be a valid network ID
+- public_sig_net_id:
+- type: string
+- description: ID of public signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_id:
+- type: string
+- description: ID of private signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_cidr:
+- type: string
+- description: Private signaling network address (CIDR notation)
+- default: 192.168.1.0/24
+- private_sig_net_gateway:
+- type: string
+- description: Private signaling network gateway address
+- default: 192.168.1.254
+ flavor:
+ type: string
+ description: Flavor to use
+@@ -64,12 +44,6 @@ parameters:
+ base_mgmt_security_group:
+ type: string
+ description: ID of base security group for all Clearwater nodes (management)
+- sprout_sig_outbound_security_group:
+- type: string
+- description: ID of security group for Sprout nodes outbound traffic (signaling)
+- sprout_sig_inbound_security_group:
+- type: string
+- description: ID of security group for Sprout nodes inbound traffic (signaling)
+ repo_url:
+ type: string
+ description: URL for Clearwater repository
+@@ -81,9 +55,6 @@ parameters:
+ dns_mgmt_ip:
+ type: string
+ description: IP address for DNS server on management network
+- dns_sig_ip:
+- type: string
+- description: IP address for DNS server on signaling network
+ dnssec_key:
+ type: string
+ description: DNSSEC private key (Base64-encoded)
+@@ -114,14 +85,15 @@ resources:
+ floating_network_id: { get_param: public_mgmt_net_id }
+ port_id: { get_resource: mgmt_port }
+
+- sig_port:
+- type: OS::Neutron::Port
++ wait_condition:
++ type: OS::Heat::WaitCondition
+ properties:
+- # Specify the network ID by string to work around OpenStack issues - see https://github.com/Metaswitch/clearwater-heat/issues/18.
+- network_id: { str_replace: { params: { x: { get_param: private_sig_net_id } }, template: x } }
+- security_groups:
+- - { get_param: sprout_sig_outbound_security_group }
+- - { get_param: sprout_sig_inbound_security_group }
++ handle: {get_resource: wait_handle}
++ count: 1
++ timeout: 1200
++
++ wait_handle:
++ type: OS::Heat::WaitConditionHandle
+
+ server:
+ type: OS::Nova::Server
+@@ -132,7 +104,6 @@ resources:
+ key_name: { get_param: key_name }
+ networks:
+ - port: { get_resource: mgmt_port }
+- - port: { get_resource: sig_port }
+ user_data_format: RAW
+ user_data:
+ str_replace:
+@@ -141,14 +112,11 @@ resources:
+ __zone__: { get_param: zone }
+ __public_mgmt_ip__: { get_attr: [ mgmt_floating_ip, floating_ip_address ] }
+ __private_mgmt_ip__: { get_attr: [ mgmt_port, fixed_ips, 0, ip_address ] }
+- __private_sig_ip__: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
+- __private_sig_cidr__: { get_param: private_sig_net_cidr }
+- __private_sig_gateway__: { get_param: private_sig_net_gateway }
+ __dns_mgmt_ip__: { get_param: dns_mgmt_ip }
+- __dns_sig_ip__: { get_param: dns_sig_ip }
+ __dnssec_key__: { get_param: dnssec_key }
+ __etcd_ip__ : { get_param: etcd_ip }
+ __index__ : { get_param: index }
++ wc_notify: { get_attr: [wait_handle, curl_cli] }
+ template: |
+ #!/bin/bash
+
+@@ -156,36 +124,8 @@ resources:
+ exec > >(tee -a /var/log/clearwater-heat-sprout.log) 2>&1
+ set -x
+
+- # Set up the signaling network namespace on each boot by creating an init file and
+- # linking to it from runlevel 2 and 3
+- cat >/etc/init.d/signaling_namespace <<EOF
+- #!/bin/bash
+- # Create the signaling namespace and configure its interfaces.
+- set -e
+-
+- # Exit if the namespace is already set up.
+- ip netns list | grep -q signaling && exit 0
+-
+- # eth1 is the signaling interface (and eth0 is the management interface).
+- # We need to set eth1 up manually - only eth0 is automatically configured via DHCP.
+- ip netns add signaling
+- ip link set eth1 netns signaling
+- ip netns exec signaling ip link set dev lo up
+- ip netns exec signaling ip addr add __private_sig_ip__/$(echo __private_sig_cidr__ | cut -d / -f 2) dev eth1
+- ip netns exec signaling ip link set dev eth1 up
+- ip netns exec signaling ip route add default via __private_sig_gateway__
+- EOF
+-
+- chmod a+x /etc/init.d/signaling_namespace
+- ln -s /etc/init.d/signaling_namespace /etc/rc2.d/S01signaling_namespace
+- ln -s /etc/init.d/signaling_namespace /etc/rc3.d/S01signaling_namespace
+-
+- # Also set up the signaling namespace now.
+- /etc/init.d/signaling_namespace
+-
+ # Configure the APT software source.
+- echo 'deb __repo_url__ binary/' > /etc/apt/sources.list.d/clearwater.list
+- curl -L http://repo.cw-ngv.com/repo_key | apt-key add -
++ echo 'deb http://artifacts.opnfv.org/functest/clearwater/debian ./' > /etc/apt/sources.list.d/clearwater.list
+ apt-get update
+
+ # Configure /etc/clearwater/local_config.
+@@ -193,11 +133,8 @@ resources:
+ etcd_ip=__etcd_ip__
+ [ -n "$etcd_ip" ] || etcd_ip=__private_mgmt_ip__
+ cat > /etc/clearwater/local_config << EOF
+- signaling_namespace=signaling
+- signaling_dns_server=__dns_sig_ip__
+- management_local_ip=__private_mgmt_ip__
+- local_ip=__private_sig_ip__
+- public_ip=__private_sig_ip__
++ local_ip=__private_mgmt_ip__
++ public_ip=__private_mgmt_ip__
+ public_hostname=__index__.sprout.__zone__
+ etcd_cluster=$etcd_ip
+ EOF
+@@ -220,10 +157,10 @@ resources:
+ while ! { nsupdate -y "__zone__:__dnssec_key__" -v << EOF
+ server __dns_mgmt_ip__
+ update add sprout-__index__.__zone__. 30 $(ip2rr __public_mgmt_ip__)
+- update add __index__.sprout.__zone__. 30 $(ip2rr __private_sig_ip__)
+- update add sprout.__zone__. 30 $(ip2rr __private_sig_ip__)
+- update add scscf.sprout.__zone__. 30 $(ip2rr __private_sig_ip__)
+- update add icscf.sprout.__zone__. 30 $(ip2rr __private_sig_ip__)
++ update add __index__.sprout.__zone__. 30 $(ip2rr __public_mgmt_ip__)
++ update add sprout.__zone__. 30 $(ip2rr __public_mgmt_ip__)
++ update add scscf.sprout.__zone__. 30 $(ip2rr __public_mgmt_ip__)
++ update add icscf.sprout.__zone__. 30 $(ip2rr __public_mgmt_ip__)
+ update add sprout.__zone__. 30 NAPTR 0 0 "s" "SIP+D2T" "" _sip._tcp.sprout.__zone__.
+ update add _sip._tcp.sprout.__zone__. 30 SRV 0 0 5054 __index__.sprout.__zone__.
+ update add icscf.sprout.__zone__. 30 NAPTR 0 0 "s" "SIP+D2T" "" _sip._tcp.icscf.sprout.__zone__.
+@@ -242,17 +179,23 @@ resources:
+ # Use the DNS server.
+ echo 'nameserver __dns_mgmt_ip__' > /etc/dnsmasq.resolv.conf
+ echo 'RESOLV_CONF=/etc/dnsmasq.resolv.conf' >> /etc/default/dnsmasq
+- mkdir -p /etc/netns/signaling
+- echo 'nameserver __dns_sig_ip__' > /etc/netns/signaling/resolv.conf
+ service dnsmasq force-reload
+
++ for ((i=1;i<=10;i++)); do
++ monit summary
++ test -z "$(monit summary 2>&1 |sed '1,2d' |grep -v Running |grep -v Status\ ok )" && break || sleep 60
++ done
++ clearwater-etcdctl cluster-health
++ clearwater-etcdctl member list
++ cw-check_cluster_state
++ cw-check_config_sync
++
++ wc_notify --data-binary '{"status": "SUCCESS"}'
++
+ outputs:
+ public_mgmt_ip:
+ description: IP address in public (management) network
+ value: { get_attr: [ mgmt_floating_ip, floating_ip_address ] }
+ private_mgmt_ip:
+- description: IP address in private signaling network
++ description: IP address in private management network
+ value: { get_attr: [ mgmt_port, fixed_ips, 0, ip_address ] }
+- private_sig_ip:
+- description: IP address in private signaling network
+- value: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
+diff --git a/vellum.yaml b/vellum.yaml
+index aab71f9..de15fcf 100644
+--- a/vellum.yaml
++++ b/vellum.yaml
+@@ -23,26 +23,6 @@ parameters:
+ constraints:
+ - custom_constraint: neutron.network
+ description: Must be a valid network ID
+- public_sig_net_id:
+- type: string
+- description: ID of public signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_id:
+- type: string
+- description: ID of private signaling network
+- constraints:
+- - custom_constraint: neutron.network
+- description: Must be a valid network ID
+- private_sig_net_cidr:
+- type: string
+- description: Private signaling network address (CIDR notation)
+- default: 192.168.1.0/24
+- private_sig_net_gateway:
+- type: string
+- description: Private signaling network gateway address
+- default: 192.168.1.254
+ flavor:
+ type: string
+ description: Flavor to use
+@@ -64,12 +44,6 @@ parameters:
+ base_mgmt_security_group:
+ type: string
+ description: ID of base security group for all Clearwater nodes (management)
+- vellum_sig_outbound_security_group:
+- type: string
+- description: ID of security group for Vellum nodes outbound traffic (signaling)
+- vellum_sig_inbound_security_group:
+- type: string
+- description: ID of security group for Vellum nodes inbound traffic (signaling)
+ repo_url:
+ type: string
+ description: URL for Clearwater repository
+@@ -81,9 +55,6 @@ parameters:
+ dns_mgmt_ip:
+ type: string
+ description: IP address for DNS server on management network
+- dns_sig_ip:
+- type: string
+- description: IP address for DNS server on signaling network
+ dnssec_key:
+ type: string
+ description: DNSSEC private key (Base64-encoded)
+@@ -114,14 +85,15 @@ resources:
+ floating_network_id: { get_param: public_mgmt_net_id }
+ port_id: { get_resource: mgmt_port }
+
+- sig_port:
+- type: OS::Neutron::Port
++ wait_condition:
++ type: OS::Heat::WaitCondition
+ properties:
+- # Specify the network ID by string to work around OpenStack issues - see https://github.com/Metaswitch/clearwater-heat/issues/18.
+- network_id: { str_replace: { params: { x: { get_param: private_sig_net_id } }, template: x } }
+- security_groups:
+- - { get_param: vellum_sig_outbound_security_group }
+- - { get_param: vellum_sig_inbound_security_group }
++ handle: {get_resource: wait_handle}
++ count: 1
++ timeout: 1200
++
++ wait_handle:
++ type: OS::Heat::WaitConditionHandle
+
+ server:
+ type: OS::Nova::Server
+@@ -132,7 +104,6 @@ resources:
+ key_name: { get_param: key_name }
+ networks:
+ - port: { get_resource: mgmt_port }
+- - port: { get_resource: sig_port }
+ user_data_format: RAW
+ user_data:
+ str_replace:
+@@ -141,51 +112,22 @@ resources:
+ __zone__: { get_param: zone }
+ __public_mgmt_ip__: { get_attr: [ mgmt_floating_ip, floating_ip_address ] }
+ __private_mgmt_ip__: { get_attr: [ mgmt_port, fixed_ips, 0, ip_address ] }
+- __private_sig_ip__: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
+- __private_sig_cidr__: { get_param: private_sig_net_cidr }
+- __private_sig_gateway__: { get_param: private_sig_net_gateway }
+ __dns_mgmt_ip__: { get_param: dns_mgmt_ip }
+- __dns_sig_ip__: { get_param: dns_sig_ip }
+ __dnssec_key__: { get_param: dnssec_key }
+ __etcd_ip__ : { get_param: etcd_ip }
+ __index__ : { get_param: index }
++ wc_notify: { get_attr: [wait_handle, curl_cli] }
+ template: |
+ #!/bin/bash
+
+ # Log all output to file.
+ exec > >(tee -a /var/log/clearwater-heat-vellum.log) 2>&1
+ set -x
+-
+- # Set up the signaling network namespace on each boot by creating an init file and
+- # linking to it from runlevel 2 and 3
+- cat >/etc/init.d/signaling_namespace <<EOF
+- #!/bin/bash
+- # Create the signaling namespace and configure its interfaces.
+- set -e
+-
+- # Exit if the namespace is already set up.
+- ip netns list | grep -q signaling && exit 0
+-
+- # eth1 is the signaling interface (and eth0 is the management interface).
+- # We need to set eth1 up manually - only eth0 is automatically configured via DHCP.
+- ip netns add signaling
+- ip link set eth1 netns signaling
+- ip netns exec signaling ip link set dev lo up
+- ip netns exec signaling ip addr add __private_sig_ip__/$(echo __private_sig_cidr__ | cut -d / -f 2) dev eth1
+- ip netns exec signaling ip link set dev eth1 up
+- ip netns exec signaling ip route add default via __private_sig_gateway__
+- EOF
+-
+- chmod a+x /etc/init.d/signaling_namespace
+- ln -s /etc/init.d/signaling_namespace /etc/rc2.d/S01signaling_namespace
+- ln -s /etc/init.d/signaling_namespace /etc/rc3.d/S01signaling_namespace
+-
+- # Also set up the signaling namespace now.
+- /etc/init.d/signaling_namespace
++ sleep 180
++ sysctl -w net.ipv6.conf.lo.disable_ipv6=0
+
+ # Configure the APT software source.
+- echo 'deb __repo_url__ binary/' > /etc/apt/sources.list.d/clearwater.list
+- curl -L http://repo.cw-ngv.com/repo_key | apt-key add -
++ echo 'deb http://artifacts.opnfv.org/functest/clearwater/debian ./' > /etc/apt/sources.list.d/clearwater.list
+ apt-get update
+
+ # Configure /etc/clearwater/local_config.
+@@ -193,11 +135,8 @@ resources:
+ etcd_ip=__etcd_ip__
+ [ -n "$etcd_ip" ] || etcd_ip=__private_mgmt_ip__
+ cat > /etc/clearwater/local_config << EOF
+- signaling_namespace=signaling
+- signaling_dns_server=__dns_sig_ip__
+- management_local_ip=__private_mgmt_ip__
+- local_ip=__private_sig_ip__
+- public_ip=__private_sig_ip__
++ local_ip=__private_mgmt_ip__
++ public_ip=__private_mgmt_ip__
+ public_hostname=__index__.vellum.__zone__
+ etcd_cluster=$etcd_ip
+ EOF
+@@ -206,7 +145,7 @@ resources:
+ mkdir -p /etc/chronos
+ cat > /etc/chronos/chronos.conf << EOF
+ [http]
+- bind-address = __private_sig_ip__
++ bind-address = __private_mgmt_ip__
+ bind-port = 7253
+ threads = 50
+
+@@ -218,7 +157,7 @@ resources:
+ enabled = true
+
+ [dns]
+- servers = __dns_sig_ip__
++ servers = __dns_mgmt_ip__
+ EOF
+
+ # Now install the software.
+@@ -239,7 +178,7 @@ resources:
+ while ! { nsupdate -y "__zone__:__dnssec_key__" -v << EOF
+ server __dns_mgmt_ip__
+ update add vellum-__index__.__zone__. 30 $(ip2rr __public_mgmt_ip__)
+- update add vellum.__zone__. 30 $(ip2rr __private_sig_ip__)
++ update add vellum.__zone__. 30 $(ip2rr __public_mgmt_ip__)
+ send
+ EOF
+ } && [ $retries -lt 10 ]
+@@ -252,10 +191,19 @@ resources:
+ # Use the DNS server.
+ echo 'nameserver __dns_mgmt_ip__' > /etc/dnsmasq.resolv.conf
+ echo 'RESOLV_CONF=/etc/dnsmasq.resolv.conf' >> /etc/default/dnsmasq
+- mkdir -p /etc/netns/signaling
+- echo 'nameserver __dns_sig_ip__' > /etc/netns/signaling/resolv.conf
+ service dnsmasq force-reload
+
++ for ((i=1;i<=10;i++)); do
++ monit summary
++ test -z "$(monit summary 2>&1 |sed '1,2d' |grep -v Running |grep -v Status\ ok )" && break || sleep 60
++ done
++ clearwater-etcdctl cluster-health
++ clearwater-etcdctl member list
++ cw-check_cluster_state
++ cw-check_config_sync
++
++ wc_notify --data-binary '{"status": "SUCCESS"}'
++
+ outputs:
+ public_mgmt_ip:
+ description: IP address in public management network
+@@ -263,6 +211,3 @@ outputs:
+ private_mgmt_ip:
+ description: IP address in private management network
+ value: { get_attr: [ mgmt_port, fixed_ips, 0, ip_address ] }
+- private_sig_ip:
+- description: IP address in private signaling network
+- value: { get_attr: [ sig_port, fixed_ips, 0, ip_address ] }
diff --git a/docker/vnf/hooks/post_checkout b/docker/vnf/hooks/post_checkout
index 8d0e98124..c347524ea 100644
--- a/docker/vnf/hooks/post_checkout
+++ b/docker/vnf/hooks/post_checkout
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
from="${DOCKER_REPO%/*}/functest-core:${DOCKER_TAG}"
sed -i "s|^FROM.*$|FROM ${from}|" Dockerfile
diff --git a/docker/vnf/testcases.yaml b/docker/vnf/testcases.yaml
index 170eed0e5..6b483af6a 100644
--- a/docker/vnf/testcases.yaml
+++ b/docker/vnf/testcases.yaml
@@ -2,7 +2,6 @@
tiers:
-
name: vnf
- order: 5
description: >-
Collection of VNF test cases.
testcases:
@@ -13,8 +12,6 @@ tiers:
blocking: false
description: >-
This test case deploys the Cloudify orchestrator.
- dependencies:
- - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
run:
name: cloudify
-
@@ -27,7 +24,7 @@ tiers:
Clearwater using the Cloudify orchestrator. It also runs
some signaling traffic.
dependencies:
- - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: cloudify_ims
@@ -41,7 +38,7 @@ tiers:
Clearwater using the OpenStack Heat orchestrator.
It also runs some signaling traffic.
dependencies:
- - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: heat_ims
@@ -53,7 +50,7 @@ tiers:
description: >-
This test case is vRouter testing.
dependencies:
- - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: vyos_vrouter
@@ -66,6 +63,6 @@ tiers:
vEPC validation with Juju as VNF manager and ABoT as test
executor.
dependencies:
- - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: juju_epc
diff --git a/docs/com/css/theme/OPNFV-Berlin.css b/docs/com/css/theme/OPNFV-Berlin.css
index 9f957d6f1..34f73b4bd 100644
--- a/docs/com/css/theme/OPNFV-Berlin.css
+++ b/docs/com/css/theme/OPNFV-Berlin.css
@@ -31,13 +31,13 @@ body {
bottom: 1em;
left: 1em;
font-size: 0.5em;
-
+
}
.reveal .slides > section, .reveal .slides > section > section {
line-height: 1.3;
font-weight: inherit; }
-
+
.reveal .opnfv-title {
background-image: url("../../img/title-bg-berlin.png" no-repeat);
}
@@ -87,7 +87,7 @@ body {
.reveal h1 {
text-shadow: none; }
-
+
/*********************************************
* OTHER
diff --git a/docs/com/css/theme/OPNFV.css b/docs/com/css/theme/OPNFV.css
index 745a2a8de..c59c59f8d 100644
--- a/docs/com/css/theme/OPNFV.css
+++ b/docs/com/css/theme/OPNFV.css
@@ -30,13 +30,13 @@ body {
bottom: 1em;
left: 1em;
font-size: 0.5em;
-
+
}
.reveal .slides > section, .reveal .slides > section > section {
line-height: 1.3;
font-weight: inherit; }
-
+
.reveal .opnfv-title {
background-image: url("../../img/title-bg.png" no-repeat);
}
@@ -83,7 +83,7 @@ body {
.reveal h1 {
text-shadow: none; }
-
+
/*********************************************
* OTHER
diff --git a/docs/com/pres/Summit/Berlin-2016/conversation.html b/docs/com/pres/Summit/Berlin-2016/conversation.html
index 356c2ad1e..5c1e18450 100644
--- a/docs/com/pres/Summit/Berlin-2016/conversation.html
+++ b/docs/com/pres/Summit/Berlin-2016/conversation.html
@@ -215,7 +215,7 @@
</div>
<div class='footer'>
- <img src="../../../img/logo-OPNFV-Berlin.png" alt="OPNFV logo">
+ <img src="../../../img/logo-OPNFV-Berlin.png" alt="OPNFV logo">
</div>
</div>
diff --git a/docs/com/pres/Summit/Berlin-2016/summit-Berlin.html b/docs/com/pres/Summit/Berlin-2016/summit-Berlin.html
index 97fa66c18..2b3b3b4ef 100644
--- a/docs/com/pres/Summit/Berlin-2016/summit-Berlin.html
+++ b/docs/com/pres/Summit/Berlin-2016/summit-Berlin.html
@@ -81,7 +81,7 @@
</section>
<section data-markdown>
## so concretely...
- * Validate scenarios for the release
+ * Validate scenarios for the release
* Give confidence on OPNFV fresh releases
* Ensure consistancy towards installers
* Ensure End to End interoperability
@@ -135,7 +135,7 @@
* 2 installers: Foreman/Fuel
* Lots of manual operations (reporting, documentation)
</section>
- </section>
+ </section>
<section>
<section data-markdown>
# Brahmaputra
@@ -146,8 +146,8 @@
* 3 feature projects: doctor, promise, sdnvpn
* 13 Scenarios
* 4 Installers (Apex, Compass, Fuel, Joid)
- * Test result collection
- * Automatic dashboard
+ * Test result collection
+ * Automatic dashboard
</section>
<section>
<h3>Jiras</h3>
@@ -196,7 +196,7 @@
</tr>
</tbody>
</table>
- * difference of duration due to POD and test suites
+ * difference of duration due to POD and test suites
</section>
<section data-markdown>
@@ -204,7 +204,7 @@
* Tempest/Rally
* harmonizing installer related OpenStack configuration differences
* creating customized test lists
- * main challenge was resolving SDN controller interworking problems
+ * main challenge was resolving SDN controller interworking problems
* vIMS
* complete but complex test case
* very interesting to automate (pre MANO, most of Telco needs met there)
@@ -212,7 +212,7 @@
</section>
- <section>
+ <section>
<section data-markdown>
# Colorado
</section>
@@ -221,7 +221,7 @@
## What's new?
* New internal test cases: healthcheck, security
* New controler: OpenContrail?
- * New feature projects (domino, multisites, movie, parser, moon, copper, models, onos-sfc...)
+ * New feature projects (domino, multisites, movie, parser, moon, copper, models, onos-sfc...)
* ARM Support (congratulations to ENEA team!)
* Simplified feature project integration journey
</section>
@@ -255,19 +255,19 @@
* New VNFs (vEPC, vCDN, vWhatever...)
* Multi sites (e.g bgpvpn with different back ends)
* Better test coverage
- </section>
+ </section>
<section data-markdown>
## A Functional testing As a Service framework
* Scenario owner can select their relevant test cases
* Test duration estimation
* Agile dashboarding
* Analytics
- </section>
+ </section>
<section data-markdown>
## Upstream
* Rally: time to give back more
- * Functest description for ETSI?
- </section>
+ * Functest description for ETSI?
+ </section>
</section>
<section>
diff --git a/docs/com/pres/Summit/Berlin-2016/testapi.html b/docs/com/pres/Summit/Berlin-2016/testapi.html
index c40637cbf..5e56d5052 100644
--- a/docs/com/pres/Summit/Berlin-2016/testapi.html
+++ b/docs/com/pres/Summit/Berlin-2016/testapi.html
@@ -69,7 +69,7 @@
* Test cases
* Results
</section>
-
+
<section data-markdown>
## Status Currently
* From many projects
@@ -87,7 +87,7 @@
</aside>
</script>
</section>
-
+
<section data-markdown>
## Help building
* Dashboards
@@ -135,8 +135,8 @@
<li>Scripts to support databse backup/restore/update</li>
<li>Support installation</li>
<aside class='notes'>
- So you can discover and understand the capabilities of the service without
- access to source code, documentation, or through network traffic inspection,
+ So you can discover and understand the capabilities of the service without
+ access to source code, documentation, or through network traffic inspection,
and also you can interact with the TestAPI directly through swagger website.
</aside>
</ul>
@@ -148,12 +148,12 @@
<section data-markdown>
# API Evoluation
</section>
-
+
<section>
<h2> URI changes...</h2>
- <div style="text-align:left"">
+ <div style="text-align:left"">
<p> testresults.opnfv.org/<span style="color:lightblue">TestAPI</span> => <br>testresults.opnfv.org/<span style="color:yellow">test/api/v1</span> </p>
-
+
<p> /test/api/v1/<b>pods</b></p>
<p> /test/api/v1/<b>projects</b></p>
<p> /test/api/v1/projects/qtip/<b>cases</b></p>
@@ -200,7 +200,7 @@
<section>
<h2>unit tests</h2>
<pre><code class="hljs" data-trim contenteditable>
-umry8364@umry8364-Latitude-E6400:~/Dev/OPNFV/releng/utils/test/result_collection_api$ ./run_test.sh
+umry8364@umry8364-Latitude-E6400:~/Dev/OPNFV/releng/utils/test/result_collection_api$ ./run_test.sh
Tests running...
WARNING:tornado.general:404 GET /dashboard/v1/results?case=vPing&pod=zte-pod1&version=C&installer=fuel&period=5 (127.0.0.1): Project name missing
WARNING:tornado.access:404 GET /dashboard/v1/results?case=vPing&pod=zte-pod1&version=C&installer=fuel&period=5 (127.0.0.1) 2.30ms
diff --git a/docs/com/pres/compliance/compliance.md b/docs/com/pres/compliance/compliance.md
new file mode 100644
index 000000000..cbe0dbe17
--- /dev/null
+++ b/docs/com/pres/compliance/compliance.md
@@ -0,0 +1,97 @@
+# From Verification to CNTT Compliance
+
+[Cédric Ollivier](mailto:cedric.ollivier@orange.com)
+
+2019/12/04
+
+
+
+## Infrastructure Verification
+
+
+### Functest in a nutshell
+
+- verify any kind of OpenStack and Kubernetes deployments (OPNFV model)
+ including production environments
+- conform with upstream rules (OpenStack gate jobs and Kubernetes conformance
+ tests)
+- ensure that the platforms meet Network Functions Virtualization requirements
+
+
+### Functest suites
+
+- all functional tests (3000+) as defined by the upstream communities
+ (e.g. Tempest, neutron-tempest-api, Barbican, Patrole...)
+- 3 hours upstream API and dataplane benchmarking tests (Rally, VMTP and
+ Shaker)
+- Virtual Network Function deployments and testing (vIMS, vRouter and vEPC)
+
+
+
+## CNTT Compliance
+
+
+### Verification vs Compliance
+
+- verification allows skipping test if optional services (Gnocchi, Barbican,
+ etc.) or capabilities (remote console access, Neutron BGPVPN or SFC, etc.)
+ are missing
+- compliance forces here the full API descriptions as currently proposed by
+ CNTT (please see
+ [Interfaces and APIs](https://github.com/cntt-n/CNTT/blob/master/doc/ref_arch/openstack/chapters/chapter05.md))
+- then the testcase descriptions should forbid skipping any test and cover only
+ the mandatory services (and their mandatory capabilities)
+
+
+### Changelog
+
+- all the logics were already in Functest and the underlying frameworks (Rally,
+ Tempest, etc.)
+- 2 new CNTT-related containers including the new testcase descriptions were
+ published to easily verify the compliance
+- all 3 Functest SUTs (Rocky, Stein/Train and Master) are now compliant with
+ CNTT API to ensure the continuous integration
+- the benchmarking testcases doesn't validate any KPI as nothing is written in
+ CNTT documentation
+
+
+### RI verification and Compliance
+
+- CNTT Reference Implementation 1 is already continuously verified
+ ([continuous integration model](https://build.opnfv.org/ci/view/cntt/job/cntt-latest-daily/))
+- the conformance is currently failing due to a few bugs in deployments and
+ missing features
+
+**Be free to [deploy your own CNTT Compliance CI/CD toolchain](https://wiki.opnfv.org/pages/viewpage.action?pageId=32015004)
+ in a few commands**
+
+
+
+## Conclusion
+
+
+### Next steps
+
+- fix reference implementation 1 deployments and then achieve the compliance
+- port existing OPNFV testcases to Xtesting and then add them in the continuous
+ integration loop
+- update the testcase descritions according to the CNTT progress (KPI, API
+ changes)
+
+
+### Takeaways
+
+- Functest allows verifying any production Infrastructure and now checking the
+ CNTT API Compliance
+- all containers can be already consumed
+- any third-party certification should reuse the Functest CNTT-related
+ containers as they are
+- [CNTT RI continuous integration](https://build.opnfv.org/ci/view/cntt/job/cntt-latest-daily/)
+ is in place and any testcase can be smoothly added if they leverage on
+ Xtesting
+
+**Try it, and you will love it!**
+
+
+
+## Thank you
diff --git a/docs/com/pres/compliance/index.html b/docs/com/pres/compliance/index.html
new file mode 100644
index 000000000..94fc121d6
--- /dev/null
+++ b/docs/com/pres/compliance/index.html
@@ -0,0 +1,52 @@
+<html>
+<head>
+<title>From Verification to Compliance</title>
+<meta name="author" content="Cédric Ollivier">
+<meta name="viewport"
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<link rel="stylesheet" href="../reveal.js/css/reveal.css">
+<link rel="stylesheet" href="../reveal.js/css/theme/white.css">
+<link rel="stylesheet" href="../reveal.js/lib/css/zenburn.css">
+<script>
+var link = document.createElement( 'link' );
+link.rel = 'stylesheet';
+link.type = 'text/css';
+link.href = window.location.search.match( /print-pdf/gi ) ? '../reveal.js/css/print/pdf.css' : '../reveal.js/css/print/paper.css';
+document.getElementsByTagName( 'head' )[0].appendChild( link );
+</script>
+</head>
+<body>
+ <div class="reveal">
+ <div class="slides">
+ <section data-markdown="compliance.md" data-separator="^\n\n\n"
+ data-separator-vertical="^\n\n" data-separator-notes="^Note:"></section>
+ </div>
+ </div>
+ <script src="../reveal.js/lib/js/head.min.js"></script>
+ <script src="../reveal.js/js/reveal.js"></script>
+ <script>
+ Reveal.initialize({
+ dependencies : [ {
+ src : '../reveal.js/plugin/markdown/marked.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src : '../reveal.js/plugin/markdown/markdown.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src: '../reveal.js/plugin/highlight/highlight.js',
+ async: true,
+ callback: function() {
+ hljs.initHighlightingOnLoad();
+ }
+ }, {
+ src: '../reveal.js/plugin/notes/notes.js',
+ async: true
+ } ]
+ });
+ </script>
+</body>
+</html>
diff --git a/docs/com/pres/dockerslicing/dockerslicing.md b/docs/com/pres/dockerslicing/dockerslicing.md
index a66453248..0d1ce5e21 100644
--- a/docs/com/pres/dockerslicing/dockerslicing.md
+++ b/docs/com/pres/dockerslicing/dockerslicing.md
@@ -63,7 +63,7 @@
### 8 Functest containers
-```bash
+```shell
$ sudo docker search opnfv |grep functest-
opnfv/functest-core OPNFV Functest core image
opnfv/functest-restapi OPNFV Functest restapi image
diff --git a/docs/com/pres/euphrates_functest_evolution/euphrates.md b/docs/com/pres/euphrates_functest_evolution/euphrates.md
index 49aab16cd..2c3105539 100644
--- a/docs/com/pres/euphrates_functest_evolution/euphrates.md
+++ b/docs/com/pres/euphrates_functest_evolution/euphrates.md
@@ -120,7 +120,7 @@ export OS_IDENTITY_API_VERSION=3
#### Retrieve all the images
```
-mkdir -p images && wget -q -O- https://git.opnfv.org/functest/plain/functest/ci/download_images.sh | bash -s -- images && ls -1 images/*
+mkdir -p images && wget -q -O- https://git.opnfv.org/functest/plain/functest/ci/download_images.sh | sh -s -- images && ls -1 images/*
images/CentOS-7-aarch64-GenericCloud.qcow2
images/CentOS-7-aarch64-GenericCloud.qcow2.xz
images/CentOS-7-x86_64-GenericCloud.qcow2
diff --git a/docs/com/pres/functest2019/functest2019.md b/docs/com/pres/functest2019/functest2019.md
new file mode 100644
index 000000000..48f01cb0c
--- /dev/null
+++ b/docs/com/pres/functest2019/functest2019.md
@@ -0,0 +1,105 @@
+# Functest 2019
+
+[Cédric Ollivier](mailto:cedric.ollivier@orange.com)
+
+2019/01/08
+
+
+
+## Gates
+
+
+### Today's Verify -1
+
+- one error is detected by yamllint, pep8, pylint, ansible-lint, bashate or
+ doc8
+- one unit test fails (py27 and py35)
+- specific modules are not rated 10/10 by pylint
+- our Framework is not fully covered
+- unix permissions are wrong
+- one doc cannot be generated without warning
+
+Please see [tox.ini](https://git.opnfv.org/functest/tree/tox.ini) for details
+
+
+### Great! But
+
+- the current gate checks all coding rules, our Framework and all interfaces
+to third-parties but **not our testcases**
+- it doesn't break **the circular dependencies** between Installers and
+Functest (Installers ask for a trustable healthcheck but we need results of
+"Installer runs" as prerequisites)
+
+Our testcases have still **to be verified by hand** what differs from
+OpenStack Workflow.
+
+
+### Functional gating
+
+- we need to run all Functest patches before merge against reference
+plateforms (OpenStack and Kubernetes)
+- a voting job must forbid the merge if one test fails (as the workflow
+process implemented by OpenStack)
+
+
+### Improve the current daily model
+
+- all Functest jobs are linked to the OPNFV installers and can hardly be
+ reused by endusers
+- all test suites are run sequentially
+- rally_full is excluded due to its duration (~3 hours)
+- all possible remaining resources are cleant when installing the scenarios
+
+**It's fine for gating installers but not for verifying that Functest supports parallel and live testing**
+
+
+### New Xtesting Ansible role
+
+- deploy anywhere the full OPNFV CI/CD toolchain in few commands
+- easily add external bots voting in reviews
+- produce all Xtesting-based fonctional jobs (Xtesting, Functest and Functest
+ Kubernetes) in Releng
+- could be instanciated for testing services out of the infrastructure domain
+
+**It's already in a [good shape](https://lists.opnfv.org/g/opnfv-tech-discuss/message/22552). [Try it!](https://wiki.opnfv.org/pages/viewpage.action?pageId=32015004)**
+
+
+
+## Quality Assurance
+
+**Functest is matching the OpenStack Quality Golden rules**
+
+
+### Pylint and coverage (started from E release)
+- only need to refactor several vnf testcases and to remove duplicated code
+- document well and cover Functest utils: they are reused by
+OPNFV third-parties (SFC, SDNVPN)
+
+** Functest will be rated 10/10 very soon**
+
+
+### releasing
+
+- Functest could be also released as a classical Python packages like Xtesting(
+[PyPI](https://pypi.python.org/pypi))
+- Xtesting and Functest could be released as GNU/Linux distribution packages
+
+
+
+## other challenges
+
+
+### proposals
+
+- integrate Rally and Tempest as core modules in Functest (we do merge tempest.py and
+ conf_utils.py)
+- deploy cloud-native VNF (Clearwater IMS?)
+- why not leveraging on OpenStack middlewares such as
+ [oslo.config](https://docs.openstack.org/oslo.config/latest/)?
+- promote our VNF testcases in the upstream communities
+
+**Any new testcase is more than welcome!**
+
+
+
+## Thank you
diff --git a/docs/com/pres/functest2019/index.html b/docs/com/pres/functest2019/index.html
new file mode 100644
index 000000000..33dc9a9f2
--- /dev/null
+++ b/docs/com/pres/functest2019/index.html
@@ -0,0 +1,52 @@
+<html>
+<head>
+<title>Functest 2019</title>
+<meta name="author" content="Cédric Ollivier">
+<meta name="viewport"
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<link rel="stylesheet" href="../reveal.js/css/reveal.css">
+<link rel="stylesheet" href="../reveal.js/css/theme/white.css">
+<link rel="stylesheet" href="../reveal.js/lib/css/zenburn.css">
+<script>
+var link = document.createElement( 'link' );
+link.rel = 'stylesheet';
+link.type = 'text/css';
+link.href = window.location.search.match( /print-pdf/gi ) ? '../reveal.js/css/print/pdf.css' : '../reveal.js/css/print/paper.css';
+document.getElementsByTagName( 'head' )[0].appendChild( link );
+</script>
+</head>
+<body>
+ <div class="reveal">
+ <div class="slides">
+ <section data-markdown="functest2019.md" data-separator="^\n\n\n"
+ data-separator-vertical="^\n\n" data-separator-notes="^Note:"></section>
+ </div>
+ </div>
+ <script src="../reveal.js/lib/js/head.min.js"></script>
+ <script src="../reveal.js/js/reveal.js"></script>
+ <script>
+ Reveal.initialize({
+ dependencies : [ {
+ src : '../reveal.js/plugin/markdown/marked.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src : '../reveal.js/plugin/markdown/markdown.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src: '../reveal.js/plugin/highlight/highlight.js',
+ async: true,
+ callback: function() {
+ hljs.initHighlightingOnLoad();
+ }
+ }, {
+ src: '../reveal.js/plugin/notes/notes.js',
+ async: true
+ } ]
+ });
+ </script>
+</body>
+</html>
diff --git a/docs/com/pres/functest2020/functest2020.md b/docs/com/pres/functest2020/functest2020.md
new file mode 100644
index 000000000..a81667939
--- /dev/null
+++ b/docs/com/pres/functest2020/functest2020.md
@@ -0,0 +1,61 @@
+# Functest 2020
+
+[Cédric Ollivier](mailto:cedric.ollivier@orange.com)
+
+2020/01/16
+
+
+
+## What's new in Jerma?
+
+
+### Better test case verification
+
+- switch to Ceph in our Functest SUTs
+- add Neutron features in our SUTs to improve the case verification
+- test all capabilities possible (e.g. vnc_console)
+- verify automatically the CNTT-related containers into additional to the
+ classical ones
+- harden xrally_kubernetes
+
+**Functest SUTs are compliant to CNTT RC**
+
+
+### New test cases
+
+- tempest_horizon
+- tempest_keystone
+- tempest_cinder
+- refstack_platform
+- refstack_object
+- octavia
+- xrally_kubernetes
+
+
+### New usage
+
+- **support CNTT RC (API testing, API and dataplane benchmarking, VNF onboarding and testing)**
+- verify ONAP WindRiver OpenLab via Functest CI in a VM ("Inception model")
+- allow minimal l2-only testing via Rally
+
+**still pushing the limit!**
+
+
+
+## Kali (K-release)
+
+
+### Ideas:
+
+- finish updating to Alpine 3.11 and Python 3.8
+- finish KloudBuster integration (it has to be updated to Python3 first)
+- add tempest-stress
+- update and possibly add heat-tempest-plugin
+- add cyborg-tempest-plugin? ironic-tempest-plugin ? xxx-tempest-plugin?
+- add CNF into Kubernetes testing
+
+**continuously hardening the gates and improving code quality**
+
+
+
+## Thank you
diff --git a/docs/com/pres/functest2020/index.html b/docs/com/pres/functest2020/index.html
new file mode 100644
index 000000000..88195becb
--- /dev/null
+++ b/docs/com/pres/functest2020/index.html
@@ -0,0 +1,52 @@
+<html>
+<head>
+<title>Functest 2020</title>
+<meta name="author" content="Cédric Ollivier">
+<meta name="viewport"
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<link rel="stylesheet" href="../reveal.js/css/reveal.css">
+<link rel="stylesheet" href="../reveal.js/css/theme/white.css">
+<link rel="stylesheet" href="../reveal.js/lib/css/zenburn.css">
+<script>
+var link = document.createElement( 'link' );
+link.rel = 'stylesheet';
+link.type = 'text/css';
+link.href = window.location.search.match( /print-pdf/gi ) ? '../reveal.js/css/print/pdf.css' : '../reveal.js/css/print/paper.css';
+document.getElementsByTagName( 'head' )[0].appendChild( link );
+</script>
+</head>
+<body>
+ <div class="reveal">
+ <div class="slides">
+ <section data-markdown="functest2020.md" data-separator="^\n\n\n"
+ data-separator-vertical="^\n\n" data-separator-notes="^Note:"></section>
+ </div>
+ </div>
+ <script src="../reveal.js/lib/js/head.min.js"></script>
+ <script src="../reveal.js/js/reveal.js"></script>
+ <script>
+ Reveal.initialize({
+ dependencies : [ {
+ src : '../reveal.js/plugin/markdown/marked.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src : '../reveal.js/plugin/markdown/markdown.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src: '../reveal.js/plugin/highlight/highlight.js',
+ async: true,
+ callback: function() {
+ hljs.initHighlightingOnLoad();
+ }
+ }, {
+ src: '../reveal.js/plugin/notes/notes.js',
+ async: true
+ } ]
+ });
+ </script>
+</body>
+</html>
diff --git a/docs/com/pres/gambia/gambia.md b/docs/com/pres/gambia/gambia.md
new file mode 100644
index 000000000..4a65e9905
--- /dev/null
+++ b/docs/com/pres/gambia/gambia.md
@@ -0,0 +1,178 @@
+# Functest on steroids
+
+[Cédric Ollivier](mailto:cedric.ollivier@orange.com)
+
+2019/01/08
+
+
+
+## OPNFV
+
+![OPNFV](https://docs.opnfv.org/en/stable-fraser/_images/OPNFV_testing_working_group1.png)
+<!-- .element: style="border: 0; width: 90%" -->
+
+
+
+## Verify OpenStack and Kubernetes
+
+
+### Functest in a nutshell
+
+- verify any kind of OpenStack and Kubernetes deployments
+- conform with upstream rules (OpenStack gate jobs and Kubernetes conformance
+ tests)
+- ensure that the platforms meet Network Functions Virtualization requirements
+
+
+### Functest suites
+
+- as many upstream functional tests as possible (e.g. Tempest,
+ neutron-tempest-api, Barbican, Patrole...)
+- upstream API and dataplane benchmarking tools (Rally, Vmtp and Shaker)
+- additional VNF deployments and testing (vIMS, vRouter and vEPC)
+
+**Dovetail only runs few Functest functional tests and then we have to verify
+any OPNFV-certified scenarios via Functest anyway**
+
+
+### What's new in Functest?
+
+- new testcases were quickly integrated in Functest: Patrole, Barbican, Shaker,
+ ...
+- all testcases can run in parallel to decrease the overall duration
+- the resources cleaning has been improved
+- **our testcases may be run vs VIM in production**
+- **it includes most of the OpenStack gate jobs**
+
+
+### Support of OS and K8s master
+
+| Functest | OpenStack | Kubernetes |
+| :------: | :---------: | :--------: |
+| master | master | master |
+| hunter | rocky | v1.11.3 |
+| gambia | queens | v1.11.3 |
+
+
+### < 50 Euros
+
+![Raspberry PI](raspberrypi.jpg)
+<!-- .element: style="border: 0; width: 70%" -->
+
+
+
+## Reuse of OPNFV
+
+
+### Xtesting in a nutshell
+
+- allow the developer to work only on the test suites without diving into CI/CD
+ integration
+- simplify test integration in a complete LFN-based CI/CD toolchain (e.g.
+ Jenkins, Testing Containers, Test API and dashboard)
+- allow a proper design and verify multiple components in the same CI/CD
+ toolchain (OpenStack, Kubernetes, ONAP, etc.)
+
+**Easy to use and very useful for any CI/CD toochain (unlinked to Infrastrure)**
+
+
+### A user story ONAP
+
+- all tests are run by a specialized Docker container(**<100 MB**) instead of
+the classical ONAP testing virtual machine (**> 1GB**).
+- the container mainly inherits from opnfv/xtesting and is completed by:
+ - Python dependencies
+ - all ONAP Robot Framework files retrieved from the original repositories
+ - testcases.yaml describing the testcases
+
+[Orange-OpenSource/xtesting-onap-robot](https://github.com/Orange-OpenSource/xtesting-onap-robot/)
+
+
+### What's new in Xtesting?
+
+- new ansible roles and playbooks have been developed to allow **deploying your
+ full CI/CD toolchains in few minutes** (Jenkins, Minio, TestAPI, MongoDB and
+ Docker registry)
+
+```shell
+virtualenv xtesting
+. xtesting/bin/activate
+pip install ansible docker
+ansible-galaxy install collivier.xtesting
+git clone https://gerrit.opnfv.org/gerrit/functest-xtesting functest-xtesting-src
+ansible-playbook functest-xtesting-src/ansible/site.yml
+deactivate
+```
+
+**They are already reused in Functest and by Orange out of the
+Infrastrure domain**
+
+
+
+## Collect results
+
+
+### OPNFV Test Database in a nutshell
+
+- it's a fair comparison of Neutron implementations (Agents vs SDN
+ controller)
+- it stores all verification results and all performance data from different
+ hardware over the world which could be easily postprocessed
+- it could be very useful to select the adequate opensource solutions
+ regarding metrics and capabilities
+
+
+### which Neutron backend?
+
+- most Neutron standalone and OVN scenarios pass Functest decently
+- no ODL scenarios pass the advanced testcases (benchmarking tools and
+ VNFs). It's still unclear if it's due to the Installers, ODL or POD
+ misconfigurations.
+- no Tungsten Fabric is released in Gambia
+
+**We expected that ODL results would have improved before the first Gambia
+ corrective**
+
+
+### Contrail testing (out of OPNFV)
+
+- **3.X 4.X**: mostly verified except some functional tests about
+ visibility which fail due to the falsy admin role (they can be easily
+ blacklisted)
+- **5.X**: a limited set of bugs in Contrail mostly forbid running few
+ functional tests and benchmarking tools:
+ - wrong external network listing
+ - Contrail doesn't allow booting a VM without network (and elects the wrong
+ network)
+
+
+### And performance?
+
+- OVS DPDK is not fully integrated by an OPNFV installer (Fuel is in a good
+ shape to support it)
+- the only scenario including VPP is not part of Gambia
+
+**From the time being, we can't evaluate the benefits of OVS DPDK or VPP thanks
+ to OPNFV**
+
+
+
+## Conclusion
+
+
+### Gambia
+
+- Functest and Xtesting are powerful and easy to (re)use (containers, jenkins
+ jobs, ansible playbooks, Raspberry PI, etc.).
+- the number of installers and scenarios decreased in Gambia (it's still
+ unclear regarding the overall quality). **What about OPNFV Test Database if
+ it decreases again in 2019?**
+
+
+### And beyond
+
+- test frameworks are now considered as crucial for OPNFV (see [Last OPNFV Marketing update](https://wiki.opnfv.org/download/attachments/2925933/OPNFV%20Marketing%20Update%20091818.pptx?version=1&modificationDate=1537228648000&api=v2)) and Functest and Xtesting could be
+already widely reused out of OPNFV
+- the new test-driven approach as proposed by the [OPNFV Strategic Plan](https://wiki.opnfv.org/download/attachments/2925933/OPNFV%20Strategy%20and%20Plan%20v0.5.pptx?version=1&modificationDate=1540961098000&api=v2) could increase **the quality of all
+scenarios**. But we are also suggesting to let the installers decide their
+test cases.
diff --git a/docs/com/pres/gambia/index.html b/docs/com/pres/gambia/index.html
new file mode 100644
index 000000000..db3a6aaa2
--- /dev/null
+++ b/docs/com/pres/gambia/index.html
@@ -0,0 +1,52 @@
+<html>
+<head>
+<title>Functest on steroids</title>
+<meta name="author" content="Cédric Ollivier">
+<meta name="viewport"
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<link rel="stylesheet" href="../reveal.js/css/reveal.css">
+<link rel="stylesheet" href="../reveal.js/css/theme/white.css">
+<link rel="stylesheet" href="../reveal.js/lib/css/zenburn.css">
+<script>
+var link = document.createElement( 'link' );
+link.rel = 'stylesheet';
+link.type = 'text/css';
+link.href = window.location.search.match( /print-pdf/gi ) ? '../reveal.js/css/print/pdf.css' : '../reveal.js/css/print/paper.css';
+document.getElementsByTagName( 'head' )[0].appendChild( link );
+</script>
+</head>
+<body>
+ <div class="reveal">
+ <div class="slides">
+ <section data-markdown="gambia.md" data-separator="^\n\n\n"
+ data-separator-vertical="^\n\n" data-separator-notes="^Note:"></section>
+ </div>
+ </div>
+ <script src="../reveal.js/lib/js/head.min.js"></script>
+ <script src="../reveal.js/js/reveal.js"></script>
+ <script>
+ Reveal.initialize({
+ dependencies : [ {
+ src : '../reveal.js/plugin/markdown/marked.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src : '../reveal.js/plugin/markdown/markdown.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src: '../reveal.js/plugin/highlight/highlight.js',
+ async: true,
+ callback: function() {
+ hljs.initHighlightingOnLoad();
+ }
+ }, {
+ src: '../reveal.js/plugin/notes/notes.js',
+ async: true
+ } ]
+ });
+ </script>
+</body>
+</html>
diff --git a/docs/com/pres/gambia/raspberrypi.jpg b/docs/com/pres/gambia/raspberrypi.jpg
new file mode 100644
index 000000000..60a2638f3
--- /dev/null
+++ b/docs/com/pres/gambia/raspberrypi.jpg
Binary files differ
diff --git a/docs/com/pres/oran/ftth.png b/docs/com/pres/oran/ftth.png
new file mode 100644
index 000000000..5b441d1de
--- /dev/null
+++ b/docs/com/pres/oran/ftth.png
Binary files differ
diff --git a/docs/com/pres/oran/oran.md b/docs/com/pres/oran/oran.md
new file mode 100644
index 000000000..87fba1306
--- /dev/null
+++ b/docs/com/pres/oran/oran.md
@@ -0,0 +1,90 @@
+---
+author: Cédric Ollivier
+title: OPNFV/CNTT CI assets
+date: 2020/12/01
+---
+## Continuous integration
+
+
+### A few CNTT reqs
+
+- OPNFV has built a complete CI/CD toolchain for continuously deploying and
+ testing cloud infrastructure
+- Reference conformance only requires for the local deployment of the
+ same components
+- all test cases must be delivered as **Docker containers** including the
+ common test case execution and the unified way to manage all the interactions
+
+**Integrate smoothly and deploy fastly**
+
+
+### How OPNFV/CNTT helps?
+
+- **Functest** offers a collection of state-of-the-art virtual infrastructure
+ test suites
+- **Xtesting** helps assembling sparse test cases and accelerating the adoption
+ of CI/CD best practices
+- **XtestingCI** eases deploying anywhere plug-and-play CI/CD toolchains in a
+ few commands
+- **CNTT** defines conformance suites and its playbooks leveraging this 3
+ testing frameworks
+
+**Leverage best opensource tools and practices**
+
+
+### Testing [FTTH](https://en.wikipedia.org/wiki/Fiber_to_the_x) equipment
+
+![FTTH](ftth.png)
+
+
+### Deploy your CI toolchain
+
+```
+virtualenv xtesting
+. xtesting/bin/activate
+pip install ansible
+ansible-galaxy install collivier.xtesting
+git clone https://gerrit.opnfv.org/gerrit/functest-xtesting functest-xtesting-src
+ansible-playbook functest-xtesting-src/ansible/site.yml
+deactivate
+rm -rf functest-xtesting-src xtesting
+```
+
+**More scenarios in [[1]](https://wiki.opnfv.org/pages/viewpage.action?pageId=32015004)**
+
+
+
+## Testing
+
+
+### Verif', Compliance and Interop'
+
+- verification allows skipping test if optional services or capabilities are
+ missing
+- compliance forces the full API descriptions as currently proposed by
+ CNTT and then skips all optional capability testing
+- the opensource certifications are driven by simple interoperability testing
+ (RefStack and OVP are about less than 10% of Functest. **trustability?**)
+
+**Fine tune the same test frameworks**
+
+
+### [CNTT RC1](https://build.opnfv.org/ci/view/functest/job/functest-leguer-daily/12/)
+
+![RC1](rc1.png)
+
+
+
+## Conclusion
+
+
+### Key takeaways
+
+- **test integration requirements** are crucial to smoothly assemble all
+ test cases
+- leverage **existing** OPNFV testing knowledge (projects) and experience
+ (history) by utilising the OPNFV toolchain design already in-place
+- **3000+** functional tests, **3 hours** upstream API and dataplane benchmarks
+ and VNFs automatically onboarded and tested **can be reused asis**
+
+**Keep it simple and do not reivent the wheel**
diff --git a/docs/com/pres/oran/rc1.png b/docs/com/pres/oran/rc1.png
new file mode 100644
index 000000000..9179f3bb6
--- /dev/null
+++ b/docs/com/pres/oran/rc1.png
Binary files differ
diff --git a/docs/com/pres/reveal.js b/docs/com/pres/reveal.js
-Subproject a349ff43c58c23f9c837b8ea9b5fc7d4761b8de
+Subproject 2c5396b7d347f8ee1344016f15b93d4f7840156
diff --git a/docs/com/pres/rfp/index.html b/docs/com/pres/rfp/index.html
new file mode 100644
index 000000000..538c0c8c8
--- /dev/null
+++ b/docs/com/pres/rfp/index.html
@@ -0,0 +1,52 @@
+<html>
+<head>
+<title>OPNFV and CNTT in Orange RFP</title>
+<meta name="author" content="Cédric Ollivier">
+<meta name="viewport"
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<link rel="stylesheet" href="../reveal.js/css/reveal.css">
+<link rel="stylesheet" href="../reveal.js/css/theme/white.css">
+<link rel="stylesheet" href="../reveal.js/lib/css/zenburn.css">
+<script>
+var link = document.createElement( 'link' );
+link.rel = 'stylesheet';
+link.type = 'text/css';
+link.href = window.location.search.match( /print-pdf/gi ) ? '../reveal.js/css/print/pdf.css' : '../reveal.js/css/print/paper.css';
+document.getElementsByTagName( 'head' )[0].appendChild( link );
+</script>
+</head>
+<body>
+ <div class="reveal">
+ <div class="slides">
+ <section data-markdown="rfp.md" data-separator="^\n\n\n"
+ data-separator-vertical="^\n\n" data-separator-notes="^Note:"></section>
+ </div>
+ </div>
+ <script src="../reveal.js/lib/js/head.min.js"></script>
+ <script src="../reveal.js/js/reveal.js"></script>
+ <script>
+ Reveal.initialize({
+ dependencies : [ {
+ src : '../reveal.js/plugin/markdown/marked.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src : '../reveal.js/plugin/markdown/markdown.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src: '../reveal.js/plugin/highlight/highlight.js',
+ async: true,
+ callback: function() {
+ hljs.initHighlightingOnLoad();
+ }
+ }, {
+ src: '../reveal.js/plugin/notes/notes.js',
+ async: true
+ } ]
+ });
+ </script>
+</body>
+</html>
diff --git a/docs/com/pres/rfp/rfp.md b/docs/com/pres/rfp/rfp.md
new file mode 100644
index 000000000..66f7ba9e7
--- /dev/null
+++ b/docs/com/pres/rfp/rfp.md
@@ -0,0 +1,97 @@
+# OPNFV and CNTT in Orange RFP
+
+[Cédric Ollivier](mailto:cedric.ollivier@orange.com)
+
+2020/09/19
+
+
+
+## Vision and contributions
+
+
+### Our guidelines
+
+- **automate** to bring determinism and to meet the new
+ software release rate
+- test all software layers **independently** (OpenStack, Kubernetes and VNFs)
+- run all deployment and verification jobs in **our** continous integration
+ chains
+- leverage best **opensource** tools and practices
+
+**Integrate smoothly and deploy everywhere fastly**
+
+
+### How OpenSource helps?
+
+- **Functest** offers a collection of state-of-the-art virtual infrastructure
+ test suites
+- **Xtesting** helps assembling sparse test cases and accelerating the adoption
+ of CI/CD best practices
+- **XtestingCI** eases deploying anywhere plug-and-play CI/CD toolchains in a
+ few commands
+- **CNTT** defines conformance suites and its playbooks leveraging this 3
+ softwares
+
+**Any contribution is more than welcome!
+[[1]](https://www.linkedin.com/pulse/call-functest-cntt-rc1-contributions-c%25C3%25A9dric-ollivier/)
+[[2]](https://www.linkedin.com/pulse/call-functest-cntt-rc2-contributions-c%25C3%25A9dric-ollivier/)**
+
+
+
+## CNTT/OPNFV in Orange
+
+
+### A couple of RFP requirements
+
+- the **full** CNTT reference conformance for OpenStack results and outputs
+ (Orange CNTT Field Trial is in a very good shape
+ [[1]](http://testresults.opnfv.org/functest/field_trial/)
+ [[2]](https://www.linkedin.com/pulse/cntt-field-trials-c%C3%A9dric-ollivier/))
+- the **success** of the Functest Kubernetes test suites (now released as
+ part of CNTT RC2 Baraque)
+- **first** VNF test cases running in **our** continuous integration chain
+ thanks to Xtesting and XtestingCI
+
+**It's implementing Orange and CNTT targets**
+
+
+### Orange CNTT RC1 Field Trial
+
+- helped detecting a couple of issues in CNTT RC1
+- integrated cinder backup and nova instance_password in Orange IaaS
+- to fix 10 remaining single test failures (out 2000+ functional tests, 3 hours
+ benchmarking and 3 VNFs automatically onboarded and tested)
+- to enhance Functest juju_epc to pass proxies
+
+**99,999%**
+
+
+### Wish list
+
+- to integrate **more benchmarks** in CNTT conformance (e.g. disk benchmarking)
+- to switch from the current Kubernetes interoperability testing to a **true**
+ CNTT conformance suite
+- to build the first **VNF and CNF** conformance suites (**high priority**)
+
+**We need your contribution helps!
+[[1]](https://www.linkedin.com/pulse/call-functest-cntt-rc1-contributions-c%25C3%25A9dric-ollivier/)
+[[2]](https://www.linkedin.com/pulse/call-functest-cntt-rc2-contributions-c%25C3%25A9dric-ollivier/)**
+
+
+
+## Conclusion
+
+
+### Take aways
+
+- Orange leverages OPNFV and CNTT in RFP
+- we keep contributing in both specification and implementation streams for
+ the success of Network Function Virtualization
+- we expect more OPNFV and CNTT contributions especially for VNF and CNF
+ conformance suites, our initial CNTT target
+
+**Try CNTT reference suites, you will love them!**
+
+
+
+## Thank you!
diff --git a/docs/com/pres/stockholm/chainedci.png b/docs/com/pres/stockholm/chainedci.png
new file mode 100644
index 000000000..df594cd3a
--- /dev/null
+++ b/docs/com/pres/stockholm/chainedci.png
Binary files differ
diff --git a/docs/com/pres/stockholm/ftth.png b/docs/com/pres/stockholm/ftth.png
new file mode 100644
index 000000000..5b441d1de
--- /dev/null
+++ b/docs/com/pres/stockholm/ftth.png
Binary files differ
diff --git a/docs/com/pres/stockholm/index.html b/docs/com/pres/stockholm/index.html
new file mode 100644
index 000000000..65fa37a3a
--- /dev/null
+++ b/docs/com/pres/stockholm/index.html
@@ -0,0 +1,52 @@
+<html>
+<head>
+<title>From Paris to Stockholm</title>
+<meta name="author" content="Cédric Ollivier">
+<meta name="viewport"
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<link rel="stylesheet" href="../reveal.js/css/reveal.css">
+<link rel="stylesheet" href="../reveal.js/css/theme/white.css">
+<link rel="stylesheet" href="../reveal.js/lib/css/zenburn.css">
+<script>
+var link = document.createElement( 'link' );
+link.rel = 'stylesheet';
+link.type = 'text/css';
+link.href = window.location.search.match( /print-pdf/gi ) ? '../reveal.js/css/print/pdf.css' : '../reveal.js/css/print/paper.css';
+document.getElementsByTagName( 'head' )[0].appendChild( link );
+</script>
+</head>
+<body>
+ <div class="reveal">
+ <div class="slides">
+ <section data-markdown="stockholm.md" data-separator="^\n\n\n"
+ data-separator-vertical="^\n\n" data-separator-notes="^Note:"></section>
+ </div>
+ </div>
+ <script src="../reveal.js/lib/js/head.min.js"></script>
+ <script src="../reveal.js/js/reveal.js"></script>
+ <script>
+ Reveal.initialize({
+ dependencies : [ {
+ src : '../reveal.js/plugin/markdown/marked.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src : '../reveal.js/plugin/markdown/markdown.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src: '../reveal.js/plugin/highlight/highlight.js',
+ async: true,
+ callback: function() {
+ hljs.initHighlightingOnLoad();
+ }
+ }, {
+ src: '../reveal.js/plugin/notes/notes.js',
+ async: true
+ } ]
+ });
+ </script>
+</body>
+</html>
diff --git a/docs/com/pres/stockholm/stockholm.md b/docs/com/pres/stockholm/stockholm.md
new file mode 100644
index 000000000..2fe99cd6e
--- /dev/null
+++ b/docs/com/pres/stockholm/stockholm.md
@@ -0,0 +1,164 @@
+# From Paris to Stockholm
+
+[Cédric Ollivier](mailto:cedric.ollivier@orange.com)
+
+2019/06/09
+
+
+
+## Agenda
+
+
+### Agenda
+
+- Functest and Xtesting in a nutshell
+- what's new from Paris (Iruya and J-release)?
+ - code improvement
+ - functional gates
+ - switch to python3
+ - Raspberry PI
+- what's next? GSMA, CNF, ETSI...
+
+
+
+## Infrastructure verification
+
+
+### Functest in a nutshell
+
+- verify any kind of OpenStack and Kubernetes deployments (OPNFV model)
+ including production environments
+- conform with upstream rules (OpenStack gate jobs and Kubernetes conformance
+ tests)
+- ensure that the platforms meet Network Functions Virtualization requirements
+
+
+### Functest suites
+
+- all functional tests (2000+) as defined by the upstream communities
+ (e.g. Tempest, neutron-tempest-api, Barbican, Patrole...)
+- upstream API and dataplane benchmarking tools (Rally, VMTP and Shaker)
+- Virtual Network Function deployments and testing (vIMS, vRouter and vEPC)
+
+
+
+### Network automation journey
+
+
+### Xtesting in a nutshell
+
+- allow the developer to work only on the test suites without diving into
+ CI/CD integration
+- simplify test integration in a complete LFN-based CI/CD toolchain (e.g.
+ Jenkins, Testing Containers, Test API and dashboard)
+- allow a proper design and verify multiple components in the same CI/CD
+ toolchain (OpenStack, Kubernetes, ONAP, etc.)
+
+**Easy to use and very useful for any CI/CD toolchain**
+
+
+### Chained CI
+
+![OPNFV](chainedci.png)
+<!-- .element: style="border: 0" -->
+
+
+### Testing [FTTH](https://en.wikipedia.org/wiki/Fiber_to_the_x) equipment
+
+![OPNFV](ftth.png)
+<!-- .element: style="border: 0; width: 90%" -->
+
+
+### Demo
+
+- describe the testcase execution
+- build and publish your container
+- list your test in the toolchain description
+- deploy your own toolchain in a few commands
+
+https://wiki.opnfv.org/pages/viewpage.action?pageId=32015004
+
+
+
+## What's new from Paris (Iruya and J-release)
+
+
+### Code improvement
+
+- all patches are now verified by [bandit](https://github.com/PyCQA/bandit) (in
+ addition to yamllint, pep8, pylint, ansible-lint and bashate. Please see
+ [tox.ini](https://git.opnfv.org/functest/tree/tox.ini) for details).
+- 10/10 by pylint is now enforced for all
+ Functest packages
+
+**we still need python3.6 in build servers to run our unit tests vs python3**
+
+
+### Functional Gates
+
+- live-migration, VMTP and Shaker are now verified in all gates (pre and post
+ merge)
+- Functest is continuously executed up to 4 tests in parallel verifying our
+ reference OpenStack/Kubernetes
+- we continuously check the remaining resources after multiple runs (they only
+ remain a few region and volume leaks which are being fixed)
+
+
+### Switch to python3
+
+- all latest Functest containers switched to python3 as default (Functest has
+ supported both python2 and python3 via six for a while)
+- all missing decode/encode calls are backported to Hunter and Iruya
+- VMTP has been updated to keep the same testcase list
+- our patch about Cloudify REST client will be published upstream if the
+ project is still active
+
+
+### Raspberry PI
+
+- travis-ci.org allows us to continuously cross-compile containers (Hunter,
+ Iruya and latest) for arm (Raspberry PI) and arm64
+- no additional configuration is required (Docker manifest allows an unify way
+ to run the containers whatever the architectures)
+- only testcases leveraging on go have not yet been ported (juju_epc and
+ Kubernetes conformance tests)
+
+**Try it, and you will love it!**
+
+
+### New testcases
+
+- refstack_platform and refstack_object (already part of tempest_full) are now
+ dedicated testcases in Functest
+- tempest_slow is on our agenda to keep conforming with OpenStack gates
+
+
+### New opportunities
+
+- a few indentified opportunities about
+[CNF](https://www.cncf.io/announcement/2019/02/25/cncf-launches-cloud-native-network-functions-cnf-testbed/):
+[Clearwater Ims via Kubernetes](https://github.com/Metaswitch/clearwater-docker/)
+and [xrally-kubernetes](https://github.com/xrally/xrally-kubernetes)
+- GSMA should come with new testcases needs (Functest can already be executed
+ vs the current profiles)
+- ETSI could leverage on Xtesting to package its testcases
+
+
+
+## Conclusion
+
+
+### Takeaways
+
+- Xtesting is a key helper from first tests to full end2end service testing
+- Functest allows verifying production Infrastructure and is breaking the
+ classical preproduction/production model
+- And we are still pushing the limits:
+ - python packages
+ - GNU/Linux packages
+
+**Upstream first! Try them, and you will love them! **
+
+
+
+## Thank you
diff --git a/docs/com/pres/vevent202004/index.html b/docs/com/pres/vevent202004/index.html
new file mode 100644
index 000000000..7c1118242
--- /dev/null
+++ b/docs/com/pres/vevent202004/index.html
@@ -0,0 +1,52 @@
+<html>
+<head>
+<title>2020 April Virtual Technical Event</title>
+<meta name="author" content="Cédric Ollivier">
+<meta name="viewport"
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<link rel="stylesheet" href="../reveal.js/css/reveal.css">
+<link rel="stylesheet" href="../reveal.js/css/theme/white.css">
+<link rel="stylesheet" href="../reveal.js/lib/css/zenburn.css">
+<script>
+var link = document.createElement( 'link' );
+link.rel = 'stylesheet';
+link.type = 'text/css';
+link.href = window.location.search.match( /print-pdf/gi ) ? '../reveal.js/css/print/pdf.css' : '../reveal.js/css/print/paper.css';
+document.getElementsByTagName( 'head' )[0].appendChild( link );
+</script>
+</head>
+<body>
+ <div class="reveal">
+ <div class="slides">
+ <section data-markdown="vevent202004.md" data-separator="^\n\n\n"
+ data-separator-vertical="^\n\n" data-separator-notes="^Note:"></section>
+ </div>
+ </div>
+ <script src="../reveal.js/lib/js/head.min.js"></script>
+ <script src="../reveal.js/js/reveal.js"></script>
+ <script>
+ Reveal.initialize({
+ dependencies : [ {
+ src : '../reveal.js/plugin/markdown/marked.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src : '../reveal.js/plugin/markdown/markdown.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src: '../reveal.js/plugin/highlight/highlight.js',
+ async: true,
+ callback: function() {
+ hljs.initHighlightingOnLoad();
+ }
+ }, {
+ src: '../reveal.js/plugin/notes/notes.js',
+ async: true
+ } ]
+ });
+ </script>
+</body>
+</html>
diff --git a/docs/com/pres/vevent202004/vevent202004.md b/docs/com/pres/vevent202004/vevent202004.md
new file mode 100644
index 000000000..a7f8b5dc4
--- /dev/null
+++ b/docs/com/pres/vevent202004/vevent202004.md
@@ -0,0 +1,99 @@
+# CNTT RC April 2020 and beyond
+
+[Cédric Ollivier](mailto:cedric.ollivier@orange.com)
+
+2020/04/21
+
+
+
+## CNTT RC status
+
+
+### Functest SUTs
+
+- ease verifying automatically the CNTT-related containers (5 SUTs in total)
+- mostly conformed with OpenStack reference implementations except:
+ - all use Ceph and Ceph RadosGW
+ - one SUT leverages on OVN to check RA1 Chapter5 vs SDN Controllers
+- OpenStack and Kubernetes are not redeployed between 2 runs as opposed to
+ [CNTT RI](https://build.opnfv.org/ci/view/cntt/job/cntt-latest-daily/102/)
+
+**Functest SUTs are compliant to CNTT RC**
+
+
+### RC verification vs Neutron
+
+- all branches are successful vs Neutron reference implementation:
+ - [Functest Hunter (Rocky)](https://build.opnfv.org/ci/view/functest/job/functest-hunter-daily/485/)
+ - [Functest Iruya (Stein)](https://build.opnfv.org/ci/view/functest/job/functest-iruya-daily/452/)
+ - [Functest Jerma (Train)](https://build.opnfv.org/ci/view/functest/job/functest-jerma-daily/249/)
+ - [Functest Master (next Ussuri)](https://build.opnfv.org/ci/view/functest/job/functest-latest-daily/597/)
+
+
+### RC verification vs OVN
+
+- the overall results are in a good shape as Functest master includes all latest software:
+ - [CNTT Conformance passed sucessfully](https://build.opnfv.org/ci/view/functest/job/functest-ovn-latest-daily/17/)
+ - [IaaS verification](https://build.opnfv.org/ci/view/functest/job/functest-ovn-latest-daily/17/)
+ failed due to one Rally task hanging iteration (under analysis)
+
+**RA1 Chapter 5 is compatible with external SDN controllers**
+
+
+
+## Field trial results
+
+
+### Orange IaaS
+
+- Orange IaaS verification has leveraged on the Functest containers before CNTT
+- Functest containers are also executed to verify the deployment before any VNF
+ onboarding
+- a few mandatory features are missing to fully pass CNTT Compliance
+ ([cinder backup](https://cntt-n.github.io/CNTT/doc/ref_arch/openstack/chapters/chapter05.html)
+ and [keystone security_compliance](https://cntt-n.github.io/CNTT/doc/ref_arch/openstack/chapters/chapter05.html))
+- a few extra RadosGW configurations are needed
+
+**the CNTT Conformance is in a good shape**
+
+
+
+## What's next?
+
+
+### last minute's changes:
+
+- tempest_heat was recently added in Functest IaaS verification and will be
+ tuned for CNTT compliance
+- tempest_horizon should be added into CNTT RC document (mandatory features)
+
+**they would be added into CNTT RC very soon**
+
+
+### and beyond
+
+- NFVBench and VSperf are being xtesting-ready and should be added in RC
+- a few CNTT issues are opened for developping Functest and then RC:
+ - [Run fio or dd in Functest](https://github.com/cntt-n/CNTT/issues/1477)
+ - [Add ceph bench and rbd bench into Functest](https://github.com/cntt-n/CNTT/issues/1476)
+ - [Add swift-bench in Functest](https://github.com/cntt-n/CNTT/issues/1474)
+
+**[help is needed!](https://github.com/cntt-n/CNTT/issues?q=is%3Aopen+is%3Aissue+project%3Acntt-n%2FCNTT%2F4)**
+
+
+
+## Conclusion
+
+
+### Take aways
+
+- CNTT RC1 1.0 seems good and stable
+- [RA1 Chapter 5]((https://cntt-n.github.io/CNTT/doc/ref_arch/openstack/chapters/chapter05.html)
+ is compatible with external SDN controllers
+- Orange IaaS is closed to be compliant
+
+**any contribution and RC results are more than welcome!**
+
+
+
+## Thank you
diff --git a/docs/com/pres/vevent202010/index.html b/docs/com/pres/vevent202010/index.html
new file mode 100644
index 000000000..a24c721d2
--- /dev/null
+++ b/docs/com/pres/vevent202010/index.html
@@ -0,0 +1,52 @@
+<html>
+<head>
+<title>Orange CNTT RC1 Field Trial feedbacks</title>
+<meta name="author" content="Cédric Ollivier">
+<meta name="viewport"
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<link rel="stylesheet" href="../reveal.js/css/reveal.css">
+<link rel="stylesheet" href="../reveal.js/css/theme/white.css">
+<link rel="stylesheet" href="../reveal.js/lib/css/zenburn.css">
+<script>
+var link = document.createElement( 'link' );
+link.rel = 'stylesheet';
+link.type = 'text/css';
+link.href = window.location.search.match( /print-pdf/gi ) ? '../reveal.js/css/print/pdf.css' : '../reveal.js/css/print/paper.css';
+document.getElementsByTagName( 'head' )[0].appendChild( link );
+</script>
+</head>
+<body>
+ <div class="reveal">
+ <div class="slides">
+ <section data-markdown="vevent202010.md" data-separator="^\n\n\n"
+ data-separator-vertical="^\n\n" data-separator-notes="^Note:"></section>
+ </div>
+ </div>
+ <script src="../reveal.js/lib/js/head.min.js"></script>
+ <script src="../reveal.js/js/reveal.js"></script>
+ <script>
+ Reveal.initialize({
+ dependencies : [ {
+ src : '../reveal.js/plugin/markdown/marked.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src : '../reveal.js/plugin/markdown/markdown.js',
+ condition : function() {
+ return !!document.querySelector('[data-markdown]');
+ }
+ }, {
+ src: '../reveal.js/plugin/highlight/highlight.js',
+ async: true,
+ callback: function() {
+ hljs.initHighlightingOnLoad();
+ }
+ }, {
+ src: '../reveal.js/plugin/notes/notes.js',
+ async: true
+ } ]
+ });
+ </script>
+</body>
+</html>
diff --git a/docs/com/pres/vevent202010/vevent202010.md b/docs/com/pres/vevent202010/vevent202010.md
new file mode 100644
index 000000000..b128210ac
--- /dev/null
+++ b/docs/com/pres/vevent202010/vevent202010.md
@@ -0,0 +1,62 @@
+# Orange CNTT RC1 Field Trial
+
+[Cédric Ollivier](mailto:cedric.ollivier@orange.com)
+
+2020/10/14
+
+
+
+## CNTT RC1 Field Trial
+
+
+### Orange CNTT RC1 Field Trial
+
+- helped detecting a couple of issues in CNTT RC1
+- integrated cinder backup and nova instance_password in Orange IaaS
+- to fix 10 remaining single test failures (out 2000+ functional tests, 3 hours
+ benchmarking and 3 VNFs automatically onboarded and tested)
+- to enhance Functest juju_epc to pass proxies
+
+**99,999%**
+
+
+### Orange CNTT RC1 feedbacks
+
+- we easily executed the CNTT RC1 playbook asis and no clear bug was found in
+ CNTT RC1 Baldy
+- CNTT RC1 is now used in our Orange IaaS verification in addition to the
+ classical Functest containers
+- CNTT RC1 is also executed to verify all deployments before onboarding any VNF
+- CNTT RC1 Baldy and CNTT RC2 Baraque are listed in **Orange RFP requirements**
+ (see last ONES
+ [[1]](http://testresults.opnfv.org/functest/ONES2020NA_OPNFV-CNTT_RFP.1080p.mp4))
+
+
+
+## What else?
+
+
+### Wish list
+
+- to integrate **more benchmarks** in CNTT conformance (e.g. disk benchmarking)
+- to switch from the current Kubernetes interoperability testing to a **true**
+ CNTT conformance suite
+- to build the first **VNF and CNF** conformance suites (**high priority**)
+
+**We need your contribution helps!
+[[2]](https://www.linkedin.com/pulse/call-functest-cntt-rc1-contributions-c%25C3%25A9dric-ollivier/)
+[[3]](https://www.linkedin.com/pulse/call-functest-cntt-rc2-contributions-c%25C3%25A9dric-ollivier/)**
+
+
+### New Functest opportunities
+
+- to implement live monitoring of your OpenStack and Kubernetes deployments via
+ a subset of Functest (healthcheck? new Rally tasks?)
+- to implement new functest testcases to validate and verify OpenStack upgrades
+ (new Rally tasks)?
+
+**Try Functest Leguer, you will love it [[4]](https://www.linkedin.com/pulse/opnfv-functest-leguer-out-c%25C3%25A9dric-ollivier/)**
+
+
+
+## Thank you!
diff --git a/docs/conf.py b/docs/conf.py
index 2be6a5ab7..7a8d1858d 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -175,3 +175,5 @@ texinfo_documents = [
'One line description of project.',
'Miscellaneous'),
]
+
+spelling_word_list_filename = 'spelling_wordlist.txt'
diff --git a/docs/lfreleng/_static/favicon.ico b/docs/lfreleng/_static/favicon.ico
deleted file mode 100644
index e69de29bb..000000000
--- a/docs/lfreleng/_static/favicon.ico
+++ /dev/null
diff --git a/docs/lfreleng/_static/logo.png b/docs/lfreleng/_static/logo.png
deleted file mode 100644
index cc9d17cfa..000000000
--- a/docs/lfreleng/_static/logo.png
+++ /dev/null
Binary files differ
diff --git a/docs/lfreleng/conf.py b/docs/lfreleng/conf.py
deleted file mode 100644
index b76d57db0..000000000
--- a/docs/lfreleng/conf.py
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/env python
-
-# pylint: disable=unused-wildcard-import,wildcard-import,redefined-builtin
-# pylint: disable=missing-docstring
-
-from docs_conf.conf import * # noqa
diff --git a/docs/lfreleng/conf.yaml b/docs/lfreleng/conf.yaml
deleted file mode 100644
index 7379d0765..000000000
--- a/docs/lfreleng/conf.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
----
-project_cfg: opnfv
-project: FUNCTEST
diff --git a/docs/release/release-notes/functest-release.rst b/docs/release/release-notes/functest-release.rst
index ee1e8e89f..b5e228caa 100644
--- a/docs/release/release-notes/functest-release.rst
+++ b/docs/release/release-notes/functest-release.rst
@@ -32,50 +32,53 @@ The internal test cases are:
* vping_ssh
* vping_userdata
* cinder_test
- * api_check
- * snaps_health_check
- * odl
* tempest_smoke
- * neutron-tempest-plugin-api
+ * tempest_horizon
+ * odl
+ * tempest_neutron
+ * tempest_cinder
+ * tempest_keystone
+ * tempest_heat
+ * tempest_telemetry
* rally_sanity
- * refstack_defcore
- * patrole
- * snaps_smoke
- * neutron_trunk
- * networking-bgpvpn
- * networking-sfc
- * barbican
+ * refstack_compute
+ * refstack_object
+ * refstack_platform
* tempest_full
* tempest_scenario
+ * tempest_slow
+ * patrole_admin
+ * patrole_user
+ * patrole_reader
+ * tempest_barbican
+ * tempest_octavia
+ * tempest_cyborg
* rally_full
+ * rally_jobs
+ * vmtp
+ * shaker
* cloudify
* cloudify_ims
* heat_ims
* vyos_vrouter
* juju_epc
- * vgpu
-
-The OPNFV projects integrated into Functest framework for automation are:
-
- * doctor
- * bgpvpn
- * odl-sfc
- * barometer
- * fds
- * stor4nfv_os
Kubernetes
----------
The internal test cases are:
+ * k8s_quick
* k8s_smoke
* k8s_conformance
-
-The OPNFV projects integrated into Functest framework for automation are:
-
- * stor4nfv
- * clover
+ * xrally_kubernetes
+ * kube_hunter
+ * kube_bench_master
+ * kube_bench_node
+ * xrally_kubernetes_full
+ * k8s_vims
+ * helm_vims
+ * cnf_conformance
Release Data
============
@@ -97,63 +100,34 @@ Software
* https://hub.docker.com/r/opnfv/functest-healthcheck
* https://hub.docker.com/r/opnfv/functest-smoke
* https://hub.docker.com/r/opnfv/functest-benchmarking
- * https://hub.docker.com/r/opnfv/functest-features
- * https://hub.docker.com/r/opnfv/functest-components
* https://hub.docker.com/r/opnfv/functest-vnf
+ * https://hub.docker.com/r/opnfv/functest-smoke-cntt
+ * https://hub.docker.com/r/opnfv/functest-benchmarking-cntt
Functest Docker images (Kubernetes):
* https://hub.docker.com/r/opnfv/functest-kubernetes-healthcheck
* https://hub.docker.com/r/opnfv/functest-kubernetes-smoke
- * https://hub.docker.com/r/opnfv/functest-kubernetes-features
+ * https://hub.docker.com/r/opnfv/functest-kubernetes-security
+ * https://hub.docker.com/r/opnfv/functest-kubernetes-benchmarking
+ * https://hub.docker.com/r/opnfv/functest-kubernetes-cnf
Docker tag for master: latest
Documents
---------
- * Functests Guides: https://functest.readthedocs.io/en/latest/
+ * Functest Guides: https://functest.readthedocs.io/en/latest/
* API Docs: https://functest-api.readthedocs.io/en/latest/
Version change
==============
-New test cases
---------------
-
- * tenantnetwork1
- * tenantnetwork2
- * vmready1
- * vmready2
- * singlevm1
- * singlevm2
- * cinder_test
- * neutron-tempest-plugin-api
- * rally_jobs
- * networking-bgpvpn
- * networking-sfc
- * barbican
- * vmtp
- * shaker
- * tempest_scenario
- * cloudify
- * heat_ims
- * vgpu
-
Key changes
-----------
- * update test cases and containers to `OpenStack master`_ and to
+ * update testcases and containers to `OpenStack master`_ and to
`Kubernetes master`_
- * define new scenarios to ease writing testcases vs OpenStack
- * isolate all resources created in different tenants
- * fully remove all OPNFV logics
- * publish new Jenkins jobs
- * support VIO (VMware Integrated OpenStack) and arm64 for Kubernetes
- * reduce Functest Kubernetes image sizes
- * add tempest_full and tempest_scenario in all daily jobs
- * include benchmarking tools such as Vmtp ans Shaker
- * increase functional scope by adding bgpvpn and sfc tempest plugins
.. _`OpenStack master`: https://github.com/openstack/requirements/blob/master/upper-constraints.txt
.. _`Kubernetes master`: https://github.com/kubernetes/kubernetes
@@ -161,24 +135,26 @@ Key changes
Key benefits
------------
- * the enduser can easily build its own toolchains by loading our Jenkins jobs
- * all developpers can easily verify their changes before merge
- * our testcases may be run vs VIM in production
- * all testcases can run in parallel to decrease the overall duration
- * Functest includes most of the OpenStack gate jobs
+ * the enduser can easily deploy its own `Functest toolchains`_ in few commands
+ * everyone can pick stable Functest rolling releases (latest included)
+ * Functest can verify VIM in production even on `Raspberry PI`_
+ * all testcases can run in parallel (tested with 4 executors in our gates)
+ * no remaining resources detected in our gates after multiple runs
+
+.. _`Functest toolchains`: https://github.com/collivier/ansible-role-xtesting
+.. _`Raspberry PI`: https://github.com/opnfv/functest/blob/master/PI.md
Code quality
------------
- * pylint: ~9.5/10
- * code coverage: ~70%
+ * pylint: 10.00/10
+ * code coverage: 70%
Useful links
============
- * wiki project page: https://wiki.opnfv.org/display/functest/Opnfv+Functional+Testing
- * Functest git repository: https://git.opnfv.org/cgit/functest
- * Functest CI dashboard: https://build.opnfv.org/ci/view/functest/
+ * Functest git repository: https://github.com/opnfv/functest
+ * Functest CI dashboard: http://104.154.71.112:8080/view/functest/
* JIRA dashboard: https://jira.opnfv.org/secure/Dashboard.jspa?selectPageId=10611
* Functest IRC channel: #opnfv-functest
* Reporting page: http://testresults.opnfv.org/reporting/master/functest/functest.html
diff --git a/docs/release/release-notes/index.rst b/docs/release/release-notes/index.rst
index c19d55610..25c2cbdfb 100644
--- a/docs/release/release-notes/index.rst
+++ b/docs/release/release-notes/index.rst
@@ -10,5 +10,3 @@ Functest Release Notes
:maxdepth: 4
functest-release.rst
-
-Build date: |today|
diff --git a/docs/results/euphrates/5.0/apex.html b/docs/results/euphrates/5.0/apex.html
index 2a75054c3..34f0c1503 100644
--- a/docs/results/euphrates/5.0/apex.html
+++ b/docs/results/euphrates/5.0/apex.html
@@ -307,13 +307,13 @@ $(document).ready(function (){
<th width="10%">Iteration</th>
</tr>
<tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=http://testresultS.opnfv.org/reporting>os-odl-fdio-ha</a></td>
<td><div id="gaugeScenario5"></div></td>
@@ -327,7 +327,7 @@ $(document).ready(function (){
<td>4/18</td>
<td>3</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-apex-baremetal-daily-euphrates/108/console>os-nosdn-ovs_dpdk-ha</a></td>
<td><div id="gaugeScenario8"></div></td>
@@ -341,9 +341,9 @@ $(document).ready(function (){
<td>16/18</td>
<td>2</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-apex-baremetal-daily-euphrates/139/console>os-nosdn-fdio-ha</a></td>
<td><div id="gaugeScenario12"></div></td>
@@ -357,11 +357,11 @@ $(document).ready(function (){
<td>18/20</td>
<td>3</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-apex-baremetal-daily-euphrates/121/console>os-nosdn-bar-ha</a></td>
<td><div id="gaugeScenario17"></div></td>
@@ -369,7 +369,7 @@ $(document).ready(function (){
<td>26/27</td>
<td>4</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-apex-baremetal-daily-euphrates/134/console>os-nosdn-nofeature-ha</a></td>
<td><div id="gaugeScenario19"></div></td>
@@ -413,9 +413,9 @@ $(document).ready(function (){
<td>8/30</td>
<td>4</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-apex-baremetal-daily-euphrates/114/console>os-ovn-nofeature-noha</a></td>
<td><div id="gaugeScenario7"></div></td>
@@ -423,9 +423,9 @@ $(document).ready(function (){
<td>6/18</td>
<td>2</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-apex-baremetal-daily-euphrates/136/console>os-odl-nofeature-noha</a></td>
<td><div id="gaugeScenario10"></div></td>
@@ -439,9 +439,9 @@ $(document).ready(function (){
<td>4/18</td>
<td>3</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=http://testresultS.opnfv.org/reporting>os-odl-fdio_dvr-noha</a></td>
<td><div id="gaugeScenario14"></div></td>
@@ -461,7 +461,7 @@ $(document).ready(function (){
<td>18/18</td>
<td>3</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-apex-baremetal-daily-euphrates/128/console>os-nosdn-calipso-noha</a></td>
<td><div id="gaugeScenario18"></div></td>
@@ -469,7 +469,7 @@ $(document).ready(function (){
<td>18/18</td>
<td>3</td>
</tr><tr class="tr-ok">
-
+
</tr>
</table>
@@ -489,31 +489,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th>
</tr>
<tr class="tr-weather-weather">
@@ -534,31 +534,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -582,37 +582,37 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
FDS
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -636,34 +636,34 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Doctor
*
@@ -693,37 +693,37 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
FDS
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -747,31 +747,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th>
</tr>
<tr class="tr-weather-weather">
@@ -792,31 +792,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Doctor
*
@@ -843,31 +843,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th>
</tr>
<tr class="tr-weather-weather">
@@ -888,31 +888,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Doctor
*
@@ -942,34 +942,34 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Doctor
*
@@ -996,31 +996,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th>
</tr>
<tr class="tr-weather-weather">
@@ -1041,31 +1041,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -1089,34 +1089,34 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Doctor
*
@@ -1143,37 +1143,37 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
FDS
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -1197,31 +1197,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Doctor
*
@@ -1251,31 +1251,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Doctor
*
@@ -1302,31 +1302,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Doctor
*
@@ -1356,31 +1356,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Doctor
*
@@ -1407,31 +1407,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Doctor
*
diff --git a/docs/results/euphrates/5.0/compass.html b/docs/results/euphrates/5.0/compass.html
index d62ba4d2e..b7f7a20ea 100644
--- a/docs/results/euphrates/5.0/compass.html
+++ b/docs/results/euphrates/5.0/compass.html
@@ -223,11 +223,11 @@ $(document).ready(function (){
<th width="10%">Iteration</th>
</tr>
<tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-compass-virtual-daily-euphrates/81/console>os-odl_l3-nofeature-ha</a></td>
<td><div id="gaugeScenario4"></div></td>
@@ -247,7 +247,7 @@ $(document).ready(function (){
<td>26/30</td>
<td>9</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-compass-virtual-daily-euphrates/72/console>os-nosdn-ovs_dpdk-ha</a></td>
<td><div id="gaugeScenario8"></div></td>
@@ -255,9 +255,9 @@ $(document).ready(function (){
<td>2/18</td>
<td>3</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-compass-baremetal-daily-euphrates/24/console>os-odl_l2-moon-ha</a></td>
<td><div id="gaugeScenario11"></div></td>
@@ -301,11 +301,11 @@ $(document).ready(function (){
<td>24/30</td>
<td>4</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-compass-virtual-daily-euphrates/86/console>os-nosdn-nofeature-noha</a></td>
<td><div id="gaugeScenario7"></div></td>
@@ -313,7 +313,7 @@ $(document).ready(function (){
<td>26/27</td>
<td>6</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-compass-virtual-daily-euphrates/82/console>os-nosdn-ovs_dpdk-noha</a></td>
<td><div id="gaugeScenario9"></div></td>
@@ -327,9 +327,9 @@ $(document).ready(function (){
<td>14/18</td>
<td>3</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr>
</table>
@@ -349,31 +349,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -397,34 +397,34 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
SFC
*
@@ -451,34 +451,34 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -502,31 +502,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -550,31 +550,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -598,34 +598,34 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
SFC
*
@@ -652,31 +652,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -700,31 +700,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th>
</tr>
<tr class="tr-weather-weather">
@@ -745,31 +745,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th>
</tr>
<tr class="tr-weather-weather">
@@ -790,31 +790,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -838,34 +838,34 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -889,31 +889,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
diff --git a/docs/results/euphrates/5.0/daisy.html b/docs/results/euphrates/5.0/daisy.html
index 6de8d0895..09580fc19 100644
--- a/docs/results/euphrates/5.0/daisy.html
+++ b/docs/results/euphrates/5.0/daisy.html
@@ -127,9 +127,9 @@ $(document).ready(function (){
<th width="10%">Iteration</th>
</tr>
<tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr>
</table>
@@ -149,31 +149,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
@@ -206,34 +206,34 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Domino
*
diff --git a/docs/results/euphrates/5.0/fuel@aarch64.html b/docs/results/euphrates/5.0/fuel@aarch64.html
index c8a2f2db0..aa9f1eb66 100644
--- a/docs/results/euphrates/5.0/fuel@aarch64.html
+++ b/docs/results/euphrates/5.0/fuel@aarch64.html
@@ -115,7 +115,7 @@ $(document).ready(function (){
<th width="10%">Iteration</th>
</tr>
<tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-fuel-armband-baremetal-arm-daily-euphrates/31/console>os-nosdn-nofeature-ha</a></td>
<td><div id="gaugeScenario2"></div></td>
@@ -147,9 +147,9 @@ $(document).ready(function (){
<td>1/9</td>
<td>1</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr>
</table>
@@ -169,31 +169,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
@@ -220,31 +220,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
@@ -283,34 +283,34 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
diff --git a/docs/results/euphrates/5.0/fuel@x86.html b/docs/results/euphrates/5.0/fuel@x86.html
index 3b918dd74..52b67b37f 100644
--- a/docs/results/euphrates/5.0/fuel@x86.html
+++ b/docs/results/euphrates/5.0/fuel@x86.html
@@ -151,7 +151,7 @@ $(document).ready(function (){
<th width="10%">Iteration</th>
</tr>
<tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-fuel-baremetal-daily-euphrates/40/console>os-odl-nofeature-ha</a></td>
<td><div id="gaugeScenario2"></div></td>
@@ -159,9 +159,9 @@ $(document).ready(function (){
<td>29/30</td>
<td>6</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-fuel-baremetal-daily-euphrates/38/console>os-nosdn-ovs-ha</a></td>
<td><div id="gaugeScenario5"></div></td>
@@ -193,7 +193,7 @@ $(document).ready(function (){
<td>25/27</td>
<td>10</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-fuel-virtual-daily-euphrates/91/console>os-odl-nofeature-noha</a></td>
<td><div id="gaugeScenario3"></div></td>
@@ -207,9 +207,9 @@ $(document).ready(function (){
<td>27/27</td>
<td>9</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr>
</table>
@@ -229,31 +229,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
@@ -280,34 +280,34 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
@@ -334,34 +334,34 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
ODL
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
@@ -388,31 +388,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
@@ -439,31 +439,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
@@ -490,31 +490,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
diff --git a/docs/results/euphrates/5.0/joid.html b/docs/results/euphrates/5.0/joid.html
index d58efcca1..9b6d0f4d0 100644
--- a/docs/results/euphrates/5.0/joid.html
+++ b/docs/results/euphrates/5.0/joid.html
@@ -163,7 +163,7 @@ $(document).ready(function (){
<th width="10%">Iteration</th>
</tr>
<tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-joid-baremetal-daily-euphrates/84/console>os-ocl-nofeature-ha</a></td>
<td><div id="gaugeScenario2"></div></td>
@@ -171,7 +171,7 @@ $(document).ready(function (){
<td>3/27</td>
<td>10</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-joid-baremetal-daily-euphrates/67/console>os-nosdn-openbaton-ha</a></td>
<td><div id="gaugeScenario4"></div></td>
@@ -185,7 +185,7 @@ $(document).ready(function (){
<td>2/15</td>
<td>4</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-joid-baremetal-daily-euphrates/81/console>os-nosdn-nofeature-ha</a></td>
<td><div id="gaugeScenario7"></div></td>
@@ -211,7 +211,7 @@ $(document).ready(function (){
<td>3/27</td>
<td>9</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-joid-baremetal-daily-euphrates/90/console>os-nosdn-nofeature-noha</a></td>
<td><div id="gaugeScenario3"></div></td>
@@ -219,9 +219,9 @@ $(document).ready(function (){
<td>15/27</td>
<td>9</td>
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
-
+
</tr><tr class="tr-ok">
<td><a href=https://build.opnfv.org/ci/view/functest/job/functest-joid-baremetal-daily-euphrates/88/console>os-nosdn-lxd-noha</a></td>
<td><div id="gaugeScenario6"></div></td>
@@ -229,7 +229,7 @@ $(document).ready(function (){
<td>3/15</td>
<td>9</td>
</tr><tr class="tr-ok">
-
+
</tr>
</table>
@@ -249,31 +249,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th>
</tr>
<tr class="tr-weather-weather">
@@ -294,31 +294,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th>
</tr>
<tr class="tr-weather-weather">
@@ -339,31 +339,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
@@ -390,31 +390,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
@@ -441,19 +441,19 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
Promise
*
@@ -480,19 +480,19 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
Promise
*
@@ -519,31 +519,31 @@ $(document).ready(function (){
<tr>
<th>
Health (connection)
-
+
</th><th>
Health (api)
-
+
</th><th>
Health (dhcp)
-
+
</th><th>
vPing (ssh)
-
+
</th><th>
vPing (userdata)
-
+
</th><th>
Tempest (smoke)
-
+
</th><th>
Rally (smoke)
-
+
</th><th>
Refstack
-
+
</th><th>
SNAPS
-
+
</th><th>
Promise
*
diff --git a/docs/results/js/default.css b/docs/results/js/default.css
index e32fa5fba..cbb564326 100644
--- a/docs/results/js/default.css
+++ b/docs/results/js/default.css
@@ -55,7 +55,7 @@ td{
background-color: #0095a2;
}
-h1 {
+h1 {
display: block;
font-size: 2em;
margin-top: 0.67em;
diff --git a/docs/results/js/trend.js b/docs/results/js/trend.js
index f24213382..47ee4d906 100644
--- a/docs/results/js/trend.js
+++ b/docs/results/js/trend.js
@@ -63,13 +63,13 @@ var trend = function(container, trend_data) {
.attr("d", valueline(trend_data))
.attr("stroke", "steelblue")
.attr("fill", "none");
-
+
trend_svg.selectAll(".dot")
.data(trend_data)
.enter().append("circle")
.attr("r", 2.5)
.attr("cx", function(d) { return trend_x(d.date); })
- .attr("cy", function(d) { return trend_y(d.score); });
+ .attr("cy", function(d) { return trend_y(d.score); });
return trend;
}
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
new file mode 100644
index 000000000..f4dcea507
--- /dev/null
+++ b/docs/spelling_wordlist.txt
@@ -0,0 +1,151 @@
+ABot
+admin
+adminURL
+api
+auth
+backend
+barbican
+benchmarking
+Benchmarking
+bgpvpn
+cacerts
+chan
+ci
+Clearwater
+cloudify
+Cloudify
+cnf
+cntt
+conf
+config
+dashboarding
+defcore
+Defcore
+Deliverables
+dhcp
+dockerhub
+enduser
+env
+EnvironmentVariable
+epc
+fds
+frontend
+functest
+Functest
+functionalities
+guestbook
+Guestbook
+healthcheck
+Healthcheck
+http
+https
+ims
+ini
+init
+interop
+Interop
+interoperability
+intra
+iptables
+jenkins
+Joid
+juju
+Juju
+jumphost
+Jumphost
+kube
+kubernetes
+Kubernetes
+kvm
+linux
+login
+metadata
+Metadata
+middleware
+nfv
+nofeature
+noha
+nosdn
+octavia
+odl
+onboarding
+ons
+Opendaylight
+openstack
+Openstack
+opnfv
+orchestrator
+Orchestrator
+organised
+os
+ovs
+patrole
+Patrole
+plugin
+pre
+proxified
+Reachability
+reconnection
+redis
+refactored
+refactoring
+refstack
+Refstack
+repo
+resolv
+restapi
+Restconf
+runnable
+screenshot
+sdn
+sfc
+signalling
+singlevm
+src
+su
+subfolder
+subnet
+Subnet
+subnets
+sudo
+systemctl
+Telco
+tenantnetwork
+testcase
+testcases
+TLS
+txt
+un
+url
+userdata
+userid
+username
+usr
+util
+utils
+UUID
+vdb
+vEPC
+verifier
+versioned
+vIMS
+vims
+Virtualised
+Virtualized
+vm
+VM
+vmready
+vmtp
+vnf
+Vnf
+vping
+vPing
+vrouter
+vRouter
+vyos
+wconsole
+wiki
+Workflow
+xrally
+xtesting
+yaml
diff --git a/docs/testing/developer/devguide/index.rst b/docs/testing/developer/devguide/index.rst
index 101236f27..da5485ef0 100644
--- a/docs/testing/developer/devguide/index.rst
+++ b/docs/testing/developer/devguide/index.rst
@@ -52,8 +52,6 @@ to the different tiers:
* functest-core: https://hub.docker.com/r/opnfv/functest-core/
* functest-healthcheck: https://hub.docker.com/r/opnfv/functest-healthcheck/
* functest-smoke: https://hub.docker.com/r/opnfv/functest-smoke/
- * functest-features: https://hub.docker.com/r/opnfv/functest-features/
- * functest-components: https://hub.docker.com/r/opnfv/functest-components/
* functest-vnf: https://hub.docker.com/r/opnfv/functest-vnf/
* functest-restapi: https://hub.docker.com/r/opnfv/functest-restapi/
@@ -81,9 +79,7 @@ Functest internal test cases
The internal test cases in Euphrates are:
- * api_check
* connection_check
- * snaps_health_check
* vping_ssh
* vping_userdata
* odl
@@ -105,49 +101,12 @@ The main internal test cases are in the opnfv_tests subfolder of the
repository, the internal test cases can be grouped by domain:
* sdn: odl, odl_fds
- * openstack: api_check, connection_check, snaps_health_check, vping_ssh,
- vping_userdata, tempest_*, rally_*
+ * openstack: connection_check, vping_ssh, vping_userdata, tempest_*, rally_*
* vnf: cloudify_ims
If you want to create a new test case you will have to create a new folder
under the testcases directory (See next section for details).
-Functest external test cases
-============================
-The external test cases are inherited from other OPNFV projects, especially the
-feature projects.
-
-The external test cases are:
-
- * barometer
- * bgpvpn
- * doctor
- * domino
- * fds
- * promise
- * refstack_defcore
- * snaps_smoke
- * functest-odl-sfc
- * orchestra_clearwaterims
- * orchestra_openims
- * vyos_vrouter
- * juju_vepc
-
-External test cases integrated in previous versions but not released in
-Euphrates:
-
- * copper
- * moon
- * netready
- * security_scan
-
-
-The code to run these test cases is hosted in the repository of the project.
-Please note that orchestra test cases are hosted in Functest repository and not
-in orchestra repository. Vyos_vrouter and juju_vepc code is also hosted in
-functest as there are no dedicated projects.
-
-
Functest framework
==================
@@ -167,8 +126,8 @@ The definition of the tiers has been agreed by the testing working group.
The tiers are:
* healthcheck
* smoke
+ * benchmarking
* features
- * components
* vnf
Functest abstraction classes
@@ -229,14 +188,11 @@ as follows::
|-- openstack_tacker.py
`-- openstack_utils.py
-It is recommended to use the SNAPS-OO library for deploying OpenStack
-instances. SNAPS `[4]`_ is an OPNFV project providing OpenStack utils.
-
TestAPI
=======
Functest is using the Test collection framework and the TestAPI developed by
-the OPNFV community. See `[5]`_ for details.
+the OPNFV community. See `[4]`_ for details.
Reporting
@@ -248,17 +204,10 @@ jinja2 templates `[3]`_.
Dashboard
=========
-Additional dashboarding is managed at the testing group level, see `[6]`_ for
+Additional dashboarding is managed at the testing group level, see `[5]`_ for
details.
-=======
-How TOs
-=======
-
-See How to section on Functest wiki `[7]`_
-
-
==========
References
==========
@@ -267,14 +216,10 @@ _`[1]`: http://artifacts.opnfv.org/functest/docs/configguide/index.html Functest
_`[2]`: http://artifacts.opnfv.org/functest/docs/userguide/index.html functest user guide
-_`[3]`: https://git.opnfv.org/releng-testresults/tree/reporting
-
-_`[4]`: https://git.opnfv.org/snaps/
-
-_`[5]`: http://docs.opnfv.org/en/latest/testing/testing-dev.html
+_`[3]`: https://github.com/opnfv/releng-testresults/tree/master/reporting
-_`[6]`: https://opnfv.biterg.io/goto/283dba93ca18e95964f852c63af1d1ba
+_`[4]`: https://wiki.opnfv.org/display/functest/2017+Beijing?preview=%2F11699623%2F11700523%2FTestAPI+-+test+results+collection+service.pptx
-_`[7]`: https://wiki.opnfv.org/pages/viewpage.action?pageId=7768932
+_`[5]`: https://lfanalytics.io/projects/lfn%2Fopnfv/dashboard
IRC support chan: #opnfv-functest
diff --git a/docs/testing/user/configguide/ci.rst b/docs/testing/user/configguide/ci.rst
deleted file mode 100644
index 483fb4d6e..000000000
--- a/docs/testing/user/configguide/ci.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-.. SPDX-License-Identifier: CC-BY-4.0
-
-Integration in CI
-=================
-In CI we use the Docker images and execute the appropriate commands within the
-container from Jenkins.
-
-4 steps have been defined::
- * functest-cleanup: clean existing functest dockers on the jumphost
- * functest-daily: run dockers opnfv/functest-* (healthcheck, smoke, features,
- vnf)
- * functest-store-results: push logs to artifacts
-
-See `[2]`_ for details.
-
-.. _`[2]`: https://git.opnfv.org/releng/tree/jjb/functest/functest-daily-jobs.yaml
diff --git a/docs/testing/user/configguide/configguide.rst b/docs/testing/user/configguide/configguide.rst
index d3e770afa..47c25adb1 100644
--- a/docs/testing/user/configguide/configguide.rst
+++ b/docs/testing/user/configguide/configguide.rst
@@ -13,12 +13,11 @@ Functest Dockers for OpenStack deployment
-----------------------------------------
Docker images are available on the dockerhub:
- * opnfv/functest-core
* opnfv/functest-healthcheck
* opnfv/functest-smoke
+ * opnfv/functest-smoke-cntt
* opnfv/functest-benchmarking
- * opnfv/functest-features
- * opnfv/functest-components
+ * opnfv/functest-benchmarking-cntt
* opnfv/functest-vnf
@@ -27,9 +26,14 @@ Preparing your environment
cat env::
- EXTERNAL_NETWORK=XXX
DEPLOY_SCENARIO=XXX # if not os-nosdn-nofeature-noha scenario
NAMESERVER=XXX # if not 8.8.8.8
+ EXTERNAL_NETWORK=XXX # if not first network with router:external=True
+ DASHBOARD_URL=XXX # else tempest_horizon will be skipped
+ NEW_USER_ROLE=XXX # if not member
+ SDN_CONTROLLER_IP=XXX # if odl scenario
+ VOLUME_DEVICE_NAME=XXX # if not vdb
+ FLAVOR_EXTRA_SPECS=hw:mem_page_size:large # if fdio scenarios
See section on environment variables for details.
@@ -42,25 +46,23 @@ cat env_file::
export OS_PROJECT_NAME=XXX
export OS_PASSWORD=XXX
export OS_IDENTITY_API_VERSION=3
+ export OS_REGION_NAME=XXX
See section on OpenStack credentials for details.
Create a directory for the different images (attached as a Docker volume)::
- mkdir -p images && wget -q -O- https://git.opnfv.org/functest/plain/functest/ci/download_images.sh?h=stable/fraser | bash -s -- images && ls -1 images/*
+ mkdir -p images && wget -q -O- https://git.opnfv.org/functest/plain/functest/ci/download_images.sh | sh -s -- images && ls -1 images/*
- images/CentOS-7-aarch64-GenericCloud.qcow2
- images/CentOS-7-aarch64-GenericCloud.qcow2.xz
- images/CentOS-7-x86_64-GenericCloud.qcow2
- images/cirros-0.4.0-x86_64-disk.img
- images/cirros-0.4.0-x86_64-lxc.tar.gz
- images/cloudify-manager-premium-4.0.1.qcow2
- images/shaker-image-arm64.qcow2
- images/shaker-image.qcow
+ images/cirros-0.5.1-aarch64-disk.img
+ images/cirros-0.5.1-x86_64-disk.img
+ images/cloudify-docker-manager-community-19.01.24.tar
+ images/Fedora-Cloud-Base-30-1.2.x86_64.qcow2
+ images/shaker-image-1.3.0+stretch.qcow2
images/ubuntu-14.04-server-cloudimg-amd64-disk1.img
images/ubuntu-14.04-server-cloudimg-arm64-uefi1.img
images/ubuntu-16.04-server-cloudimg-amd64-disk1.img
- images/vyos-1.1.7.img
+ images/vyos-1.1.8-amd64.qcow2
Testing healthcheck suite
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -74,23 +76,23 @@ Run healthcheck suite::
Results shall be displayed as follows::
- +----------------------------+------------------+---------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +----------------------------+------------------+---------------------+------------------+----------------+
- | connection_check | functest | healthcheck | 00:09 | PASS |
- | tenantnetwork1 | functest | healthcheck | 00:14 | PASS |
- | tenantnetwork2 | functest | healthcheck | 00:11 | PASS |
- | vmready1 | functest | healthcheck | 00:19 | PASS |
- | vmready2 | functest | healthcheck | 00:16 | PASS |
- | singlevm1 | functest | healthcheck | 00:41 | PASS |
- | singlevm2 | functest | healthcheck | 00:36 | PASS |
- | vping_ssh | functest | healthcheck | 00:46 | PASS |
- | vping_userdata | functest | healthcheck | 00:41 | PASS |
- | cinder_test | functest | healthcheck | 01:18 | PASS |
- | api_check | functest | healthcheck | 10:33 | PASS |
- | snaps_health_check | functest | healthcheck | 00:44 | PASS |
- | odl | functest | healthcheck | 00:00 | SKIP |
- +----------------------------+------------------+---------------------+------------------+----------------+
+ +--------------------------+------------------+---------------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +--------------------------+------------------+---------------------+------------------+----------------+
+ | connection_check | functest | healthcheck | 00:03 | PASS |
+ | tenantnetwork1 | functest | healthcheck | 00:05 | PASS |
+ | tenantnetwork2 | functest | healthcheck | 00:06 | PASS |
+ | vmready1 | functest | healthcheck | 00:06 | PASS |
+ | vmready2 | functest | healthcheck | 00:08 | PASS |
+ | singlevm1 | functest | healthcheck | 00:32 | PASS |
+ | singlevm2 | functest | healthcheck | 00:37 | PASS |
+ | vping_ssh | functest | healthcheck | 00:46 | PASS |
+ | vping_userdata | functest | healthcheck | 00:39 | PASS |
+ | cinder_test | functest | healthcheck | 01:05 | PASS |
+ | tempest_smoke | functest | healthcheck | 05:39 | PASS |
+ | tempest_horizon | functest | healthcheck | 01:05 | PASS |
+ | odl | functest | healthcheck | 00:00 | SKIP |
+ +--------------------------+------------------+---------------------+------------------+----------------+
NOTE: the duration is a reference and it might vary depending on your SUT.
@@ -106,93 +108,101 @@ Run smoke suite::
Results shall be displayed as follows::
- +------------------------------------+------------------+---------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +------------------------------------+------------------+---------------+------------------+----------------+
- | tempest_smoke | functest | smoke | 06:13 | PASS |
- | neutron-tempest-plugin-api | functest | smoke | 09:32 | PASS |
- | rally_sanity | functest | smoke | 29:34 | PASS |
- | rally_jobs | functest | smoke | 24:02 | PASS |
- | refstack_defcore | functest | smoke | 13:07 | PASS |
- | patrole | functest | smoke | 05:17 | PASS |
- | snaps_smoke | functest | smoke | 90:13 | PASS |
- | neutron_trunk | functest | smoke | 00:00 | SKIP |
- | networking-bgpvpn | functest | smoke | 00:00 | SKIP |
- | networking-sfc | functest | smoke | 00:00 | SKIP |
- | barbican | functest | smoke | 05:01 | PASS |
- +------------------------------------+------------------+---------------+------------------+----------------+
+ +---------------------------+------------------+---------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +---------------------------+------------------+---------------+------------------+----------------+
+ | tempest_neutron | functest | smoke | 15:30 | PASS |
+ | tempest_cinder | functest | smoke | 02:01 | PASS |
+ | tempest_keystone | functest | smoke | 01:17 | PASS |
+ | tempest_heat | functest | smoke | 22:14 | PASS |
+ | tempest_telemetry | functest | smoke | 00:00 | SKIP |
+ | rally_sanity | functest | smoke | 17:24 | PASS |
+ | refstack_compute | functest | smoke | 07:03 | PASS |
+ | refstack_object | functest | smoke | 02:09 | PASS |
+ | refstack_platform | functest | smoke | 07:31 | PASS |
+ | tempest_full | functest | smoke | 41:52 | PASS |
+ | tempest_scenario | functest | smoke | 08:42 | PASS |
+ | tempest_slow | functest | smoke | 43:42 | PASS |
+ | patrole_admin | functest | smoke | 21:06 | PASS |
+ | patrole_member | functest | smoke | 21:23 | PASS |
+ | patrole_reader | functest | smoke | 21:56 | PASS |
+ | tempest_barbican | functest | smoke | 02:30 | PASS |
+ | tempest_octavia | functest | smoke | 00:00 | SKIP |
+ | tempest_cyborg | functest | smoke | 00:00 | SKIP |
+ +---------------------------+------------------+---------------+------------------+----------------+
Note: if the scenario does not support some tests, they are indicated as SKIP.
See User guide for details.
-Testing benchmarking suite
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+Testing smoke CNTT suite
+^^^^^^^^^^^^^^^^^^^^^^^^
-Run benchmarking suite::
+Run smoke-cntt suite::
sudo docker run --env-file env \
-v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
-v $(pwd)/images:/home/opnfv/functest/images \
- opnfv/functest-benchmarking
+ opnfv/functest-smoke-cntt
Results shall be displayed as follows::
- +-------------------+------------------+----------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +-------------------+------------------+----------------------+------------------+----------------+
- | vmtp | functest | benchmarking | 18:43 | PASS |
- | shaker | functest | benchmarking | 29:45 | PASS |
- +-------------------+------------------+----------------------+------------------+----------------+
+ +-------------------------------+------------------+---------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +-------------------------------+------------------+---------------+------------------+----------------+
+ | tempest_neutron_cntt | functest | smoke | 11:35 | PASS |
+ | tempest_cinder_cntt | functest | smoke | 01:58 | PASS |
+ | tempest_keystone_cntt | functest | smoke | 01:13 | PASS |
+ | tempest_heat_cntt | functest | smoke | 22:32 | PASS |
+ | rally_sanity_cntt | functest | smoke | 17:16 | PASS |
+ | tempest_full_cntt | functest | smoke | 41:13 | PASS |
+ | tempest_scenario_cntt | functest | smoke | 08:57 | PASS |
+ | tempest_slow_cntt | functest | smoke | 35:58 | PASS |
+ +-------------------------------+------------------+---------------+------------------+----------------+
-Note: if the scenario does not support some tests, they are indicated as SKIP.
-See User guide for details.
-
-Testing features suite
-^^^^^^^^^^^^^^^^^^^^^^
+Testing benchmarking suite
+^^^^^^^^^^^^^^^^^^^^^^^^^^
-Run features suite::
+Run benchmarking suite::
sudo docker run --env-file env \
-v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
-v $(pwd)/images:/home/opnfv/functest/images \
- opnfv/functest-features
+ opnfv/functest-benchmarking
Results shall be displayed as follows::
- +-----------------------------+------------------------+------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +-----------------------------+------------------------+------------------+------------------+----------------+
- | doctor-notification | doctor | features | 00:00 | SKIP |
- | bgpvpn | sdnvpn | features | 00:00 | SKIP |
- | functest-odl-sfc | sfc | features | 00:00 | SKIP |
- | barometercollectd | barometer | features | 00:00 | SKIP |
- | fds | fastdatastacks | features | 00:00 | SKIP |
- | vgpu | functest | features | 00:00 | SKIP |
- | stor4nfv_os | stor4nfv | features | 00:00 | SKIP |
- +-----------------------------+------------------------+------------------+------------------+----------------+
+ +--------------------+------------------+----------------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +--------------------+------------------+----------------------+------------------+----------------+
+ | rally_full | functest | benchmarking | 93:03 | PASS |
+ | rally_jobs | functest | benchmarking | 27:05 | PASS |
+ | vmtp | functest | benchmarking | 17:56 | PASS |
+ | shaker | functest | benchmarking | 24:02 | PASS |
+ +--------------------+------------------+----------------------+------------------+----------------+
Note: if the scenario does not support some tests, they are indicated as SKIP.
See User guide for details.
-Testing components suite
-^^^^^^^^^^^^^^^^^^^^^^^^
+Testing benchmarking CNTT suite
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Run components suite::
+Run benchmarking-cntt suite::
sudo docker run --env-file env \
-v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
-v $(pwd)/images:/home/opnfv/functest/images \
- opnfv/functest-components
+ opnfv/functest-benchmarking-cntt
Results shall be displayed as follows::
- +--------------------------+------------------+--------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +--------------------------+------------------+--------------------+------------------+----------------+
- | tempest_full | functest | components | 49:51 | PASS |
- | tempest_scenario | functest | components | 18:50 | PASS |
- | rally_full | functest | components | 167:13 | PASS |
- +--------------------------+------------------+--------------------+------------------+----------------+
+ +-------------------------+------------------+----------------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +-------------------------+------------------+----------------------+------------------+----------------+
+ | rally_full_cntt | functest | benchmarking | 89:52 | PASS |
+ | rally_jobs_cntt | functest | benchmarking | 19:39 | PASS |
+ | vmtp | functest | benchmarking | 16:59 | PASS |
+ | shaker | functest | benchmarking | 23:43 | PASS |
+ +-------------------------+------------------+----------------------+------------------+----------------+
Testing vnf suite
^^^^^^^^^^^^^^^^^
@@ -209,21 +219,22 @@ Results shall be displayed as follows::
+----------------------+------------------+--------------+------------------+----------------+
| TEST CASE | PROJECT | TIER | DURATION | RESULT |
+----------------------+------------------+--------------+------------------+----------------+
- | cloudify | functest | vnf | 04:05 | PASS |
- | cloudify_ims | functest | vnf | 24:07 | PASS |
- | heat_ims | functest | vnf | 18:15 | PASS |
- | vyos_vrouter | functest | vnf | 15:48 | PASS |
- | juju_epc | functest | vnf | 29:38 | PASS |
+ | cloudify | functest | vnf | 05:08 | PASS |
+ | cloudify_ims | functest | vnf | 24:46 | PASS |
+ | heat_ims | functest | vnf | 33:12 | PASS |
+ | vyos_vrouter | functest | vnf | 15:53 | PASS |
+ | juju_epc | functest | vnf | 27:52 | PASS |
+----------------------+------------------+--------------+------------------+----------------+
Functest Dockers for Kubernetes deployment
------------------------------------------
Docker images are available on the dockerhub:
- * opnfv/functest-kubernetes-core
- * opnfv/functest-kubernetest-healthcheck
- * opnfv/functest-kubernetest-smoke
- * opnfv/functest-kubernetest-features
+ * opnfv/functest-kubernetes-healthcheck
+ * opnfv/functest-kubernetes-smoke
+ * opnfv/functest-kubernetes-security
+ * opnfv/functest-kubernetes-benchmarking
+ * opnfv/functest-kubernetes-cnf
Preparing your environment
^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -249,7 +260,8 @@ Results shall be displayed as follows::
+-------------------+------------------+---------------------+------------------+----------------+
| TEST CASE | PROJECT | TIER | DURATION | RESULT |
+-------------------+------------------+---------------------+------------------+----------------+
- | k8s_smoke | functest | healthcheck | 02:27 | PASS |
+ | k8s_quick | functest | healthcheck | 00:18 | PASS |
+ | k8s_smoke | functest | healthcheck | 01:14 | PASS |
+-------------------+------------------+---------------------+------------------+----------------+
Testing smoke suite
@@ -263,34 +275,72 @@ Run smoke suite::
Results shall be displayed as follows::
- +-------------------------+------------------+---------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +-------------------------+------------------+---------------+------------------+----------------+
- | k8s_conformance | functest | smoke | 57:14 | PASS |
- +-------------------------+------------------+---------------+------------------+----------------+
+ +---------------------------+------------------+---------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +---------------------------+------------------+---------------+------------------+----------------+
+ | k8s_conformance | functest | smoke | 94:26 | PASS |
+ | xrally_kubernetes | functest | smoke | 13:05 | PASS |
+ +---------------------------+------------------+---------------+------------------+----------------+
-Testing features suite
+Testing security suite
^^^^^^^^^^^^^^^^^^^^^^
-Run features suite::
+Run smoke suite::
+
+ sudo docker run -it --env-file env \
+ -v $(pwd)/config:/root/.kube/config \
+ opnfv/functest-kubernetes-security
+
+Results shall be displayed as follows::
+
+ +---------------------------+------------------+------------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +---------------------------+------------------+------------------+------------------+----------------+
+ | kube_hunter | functest | security | 00:19 | PASS |
+ | kube_bench_master | functest | security | 00:02 | PASS |
+ | kube_bench_node | functest | security | 00:01 | PASS |
+ +---------------------------+------------------+------------------+------------------+----------------+
+
+Testing benchmarking suite
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Run benchmarking suite::
+
+ sudo docker run -it --env-file env \
+ -v $(pwd)/config:/root/.kube/config \
+ opnfv/functest-kubernetes-benchmarking
+
+Results shall be displayed as follows::
+
+ +--------------------------------+------------------+----------------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +--------------------------------+------------------+----------------------+------------------+----------------+
+ | xrally_kubernetes_full | functest | benchmarking | 34:16 | PASS |
+ +--------------------------------+------------------+----------------------+------------------+----------------+
+
+Testing cnf suite
+^^^^^^^^^^^^^^^^^
+
+Run cnf suite::
sudo docker run -it --env-file env \
-v $(pwd)/config:/root/.kube/config \
- opnfv/functest-kubernetes-features
+ opnfv/functest-kubernetes-cnf
Results shall be displayed as follows::
- +----------------------+------------------+------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +----------------------+------------------+------------------+------------------+----------------+
- | stor4nfv_k8s | stor4nfv | stor4nfv | 00:00 | SKIP |
- | clover_k8s | clover | clover | 00:00 | SKIP |
- +----------------------+------------------+------------------+------------------+----------------+
+ +-------------------------+------------------+--------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +-------------------------+------------------+--------------+------------------+----------------+
+ | k8s_vims | functest | cnf | 09:06 | PASS |
+ | helm_vims | functest | cnf | 08:54 | PASS |
+ | cnf_conformance | functest | cnf | 02:00 | PASS |
+ +-------------------------+------------------+--------------+------------------+----------------+
Environment variables
=====================
-Several environement variables may be specified:
+Several environment variables may be specified:
* INSTALLER_IP=<Specific IP Address>
* DEPLOY_SCENARIO=<vim>-<controller>-<nfv_feature>-<ha_mode>
@@ -415,7 +465,7 @@ By default all the logs are put un /home/opnfv/functest/results/functest.log.
If you want to have more logs in console, you may edit the logging.ini file
manually.
Connect on the docker then edit the file located in
-/usr/lib/python2.7/site-packages/xtesting/ci/logging.ini
+/usr/lib/python3.8/site-packages/xtesting/ci/logging.ini
Change wconsole to console in the desired module to get more traces.
@@ -425,8 +475,8 @@ Configuration
You may also directly modify the python code or the configuration file (e.g.
testcases.yaml used to declare test constraints) under
-/usr/lib/python2.7/site-packages/xtesting and
-/usr/lib/python2.7/site-packages/functest
+/usr/lib/python3.8/site-packages/xtesting and
+/usr/lib/python3.8/site-packages/functest
Tips
@@ -575,7 +625,7 @@ docker container::
Note: In a Jumphost node based on the CentOS family OS, the **nc**
commands might not work. You can use the **curl** command instead.
- curl http://www.opnfv.org:80
+ curl https://www.opnfv.org/
<HTML><HEAD><meta http-equiv="content-type"
.
@@ -638,5 +688,5 @@ work with the above pre-requisite actions.
.. _`Install Docker on CentOS`: https://docs.docker.com/engine/installation/linux/centos/
.. _`Functest User Guide`: http://docs.opnfv.org/en/stable-danube/submodules/functest/docs/testing/user/userguide/index.html
.. _`images/CentOS-7-x86_64-GenericCloud.qcow2`: https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2
-.. _`images/cirros-0.4.0-x86_64-disk.img`: http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img
+.. _`images/cirros-0.5.1-x86_64-disk.img`: http://download.cirros-cloud.net/0.5.1/cirros-0.5.1-x86_64-disk.img
.. _`images/ubuntu-14.04-server-cloudimg-amd64-disk1.img`: https://cloud-images.ubuntu.com/releases/14.04/release/ubuntu-14.04-server-cloudimg-amd64-disk1.img
diff --git a/docs/testing/user/configguide/index.rst b/docs/testing/user/configguide/index.rst
index e749cb225..e5963435e 100644
--- a/docs/testing/user/configguide/index.rst
+++ b/docs/testing/user/configguide/index.rst
@@ -11,22 +11,12 @@ Functest Installation Guide
intro.rst
prerequisites.rst
configguide.rst
- ci.rst
References
==========
-`[1]`_ : Keystone and public end point constraint
-
-`[2]`_ : Functest Jenkins jobs
-
-`[3]`_ : OPNFV main site
-
-`[4]`_ : Functest wiki page
+`[1]`_ : Functest Jenkins jobs
IRC support channel: #opnfv-functest
-.. _`[1]`: https://ask.openstack.org/en/question/68144/keystone-unable-to-use-the-public-endpoint/
-.. _`[2]`: https://git.opnfv.org/releng/tree/jjb/functest/functest-daily-jobs.yaml
-.. _`[3]`: http://www.opnfv.org
-.. _`[4]`: https://wiki.opnfv.org/display/functest/Opnfv+Functional+Testing
+.. _`[1]`: https://github.com/opnfv/releng/blob/master/jjb/functest/functest.yaml
diff --git a/docs/testing/user/configguide/intro.rst b/docs/testing/user/configguide/intro.rst
index d20eb111c..02329995c 100644
--- a/docs/testing/user/configguide/intro.rst
+++ b/docs/testing/user/configguide/intro.rst
@@ -64,9 +64,6 @@ follows::
+ + + + + +
SUT = System Under Test
-Note connectivity to management network is not needed for most of the
-testcases. But it may be needed for some specific snaps tests.
-
All the libraries and dependencies needed by all of the Functest tools are
pre-installed into the Docker images. This allows running Functest on any
platform.
diff --git a/docs/testing/user/configguide/prerequisites.rst b/docs/testing/user/configguide/prerequisites.rst
index 6155882d3..dab4a9e6b 100644
--- a/docs/testing/user/configguide/prerequisites.rst
+++ b/docs/testing/user/configguide/prerequisites.rst
@@ -3,7 +3,7 @@
Prerequisites
=============
The OPNFV deployment is out of the scope of this document but it can be
-found in http://docs.opnfv.org.
+found in https://docs.opnfv.org/en/stable-hunter/.
The OPNFV platform is considered as the SUT in this document.
Several prerequisites are needed for Functest:
@@ -14,13 +14,6 @@ Several prerequisites are needed for Functest:
#. An admin/management network created on the SUT
#. Connectivity from the Jumphost to the SUT public/external network
-Some specific SNAPS tests may require a connectivity from the Jumphost to the
-SUT admin/management network but most of the test cases do not. This
-requirement can be changed by overriding the 'interface' attribute
-(OS_INTERFACE) value to 'public' in the credentials file. Another means to
-circumvent this issue would be to change the 'snaps.use_keystone' value from
-True to False.
-
WARNING: Connectivity from Jumphost is essential and it is of paramount
importance to make sure it is working before even considering to install
and run Functest. Make also sure you understand how your networking is
@@ -99,6 +92,4 @@ should thus be known. Ensure you can reach each node in the SUT, from the
Jumphost using the 'ping' command using the respective IP address on the
public/external network for each node in the SUT. The details of how to
determine the needed IP addresses for each node in the SUT may vary according
-to the used installer and are therefore ommitted here.
-
-.. _`[1]`: https://ask.openstack.org/en/question/68144/keystone-unable-to-use-the-public-endpoint/
+to the used installer and are therefore omitted here.
diff --git a/docs/testing/user/userguide/index.rst b/docs/testing/user/userguide/index.rst
index 988658747..1e73cd622 100644
--- a/docs/testing/user/userguide/index.rst
+++ b/docs/testing/user/userguide/index.rst
@@ -12,7 +12,6 @@ Functest User Guide
intro.rst
test_overview.rst
test_details.rst
- runfunctest.rst
test_results.rst
reporting.rst
troubleshooting.rst
@@ -29,7 +28,7 @@ References
`[5]`_: Clearwater vIMS blueprint
-`[6]`_: NIST web site
+`[6]`_: Security Content Automation Protocol
`[7]`_: OpenSCAP web site
@@ -41,7 +40,7 @@ References
`[11]`_: Robot Framework web site
-`[13]`_: SNAPS wiki
+`[13]`_: SNAPS
`[14]`_: vRouter
@@ -55,23 +54,23 @@ References
IRC support chan: #opnfv-functest
-.. _`[2]`: http://docs.openstack.org/developer/tempest/overview.html
-.. _`[3]`: https://rally.readthedocs.org/en/latest/index.html
-.. _`[4]`: http://events.linuxfoundation.org/sites/events/files/slides/Functest%20in%20Depth_0.pdf
+.. _`[2]`: https://docs.openstack.org/tempest/latest/
+.. _`[3]`: https://rally.readthedocs.io/en/latest/index.html
+.. _`[4]`: https://events.static.linuxfound.org/sites/events/files/slides/Functest%20in%20Depth_0.pdf
.. _`[5]`: https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater/blob/master/openstack-blueprint.yaml
-.. _`[6]`: https://scap.nist.gov/
+.. _`[6]`: https://en.wikipedia.org/wiki/Security_Content_Automation_Protocol
.. _`[7]`: https://github.com/OpenSCAP/openscap
.. _`[8]`: https://github.com/openstack/refstack-client
-.. _`[9]`: https://github.com/openstack/defcore
+.. _`[9]`: https://github.com/openstack/interop
.. _`[10]`: https://github.com/openstack/interop/blob/master/2016.08/procedure.rst
-.. _`[11]`: http://robotframework.org/
-.. _`[13]`: https://wiki.opnfv.org/display/PROJ/SNAPS-OO
+.. _`[11]`: https://robotframework.org/
+.. _`[13]`: https://git.opnfv.org/snaps/
.. _`[14]`: https://github.com/oolorg/opnfv-functest-vrouter
.. _`[15]`: https://aptira.com/testing-openstack-tempest-part-1/
.. _`[16]`: http://testresults.opnfv.org/test/
-.. _`OPNFV main site`: http://www.opnfv.org
-.. _`Functest page`: https://wiki.opnfv.org/display/functest/Opnfv+Functional+Testing
+.. _`OPNFV main site`: https://www.opnfv.org/
+.. _`Functest page`: https://github.com/opnfv/functest/
.. _`OpenRC`: http://docs.openstack.org/user-guide/common/cli_set_environment_variables_using_openstack_rc.html
.. _`Rally installation procedure`: https://rally.readthedocs.org/en/latest/tutorial/step_0_installation.html
-.. _`config_functest.yaml` : https://git.opnfv.org/cgit/functest/tree/functest/ci/config_functest.yaml
+.. _`config_functest.yaml` : https://github.com/opnfv/functest/blob/master/functest/ci/config_functest.yaml
.. _`Functest reporting`: http://testresults.opnfv.org/reporting/master/functest/status-apex.html
diff --git a/docs/testing/user/userguide/reporting.rst b/docs/testing/user/userguide/reporting.rst
index 7c8c48ece..8fad55d33 100644
--- a/docs/testing/user/userguide/reporting.rst
+++ b/docs/testing/user/userguide/reporting.rst
@@ -48,7 +48,7 @@ and features) corresponding to this scenario.
All the testcases (X) listed in the table are runnable on os-odl_l2-nofeature
scenarios.
Please note that other test cases (e.g. sfc_odl, bgpvpn) need ODL configuration
-addons and, as a consequence, specific scenario.
+add-ons and, as a consequence, specific scenario.
There are not considered as runnable on the generic odl_l2 scenario.
@@ -82,7 +82,7 @@ Therefore the scoring provides 3 types of indicators:
* the maturity: if the percentage (scoring/target scoring * 100) is high, it
means that all the tests are PASS
* the stability: as the number of iteration is included in the calculation,
- the pecentage can be high only if the scenario is run regularly (at least
+ the percentage can be high only if the scenario is run regularly (at least
more than 4 iterations over the last 10 days in CI)
In any case, the scoring is used to give feedback to the other projects and
diff --git a/docs/testing/user/userguide/runfunctest.rst b/docs/testing/user/userguide/runfunctest.rst
deleted file mode 100644
index aea8c02b7..000000000
--- a/docs/testing/user/userguide/runfunctest.rst
+++ /dev/null
@@ -1,114 +0,0 @@
-.. SPDX-License-Identifier: CC-BY-4.0
-
-Executing Functest suites
-=========================
-
-As mentioned in the :ref:`functest-install-guide`, Alpine docker containers
-have been introduced in Euphrates.
-Tier containers have been created.
-Assuming that you pulled the container and your environement is ready, you can
-simply run the tiers by typing (e.g. with functest-healthcheck)::
-
- sudo docker run --env-file env \
- -v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
- -v $(pwd)/images:/home/opnfv/functest/images \
- opnfv/functest-healthcheck
-
-You should get::
-
- +----------------------------+------------------+---------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +----------------------------+------------------+---------------------+------------------+----------------+
- | connection_check | functest | healthcheck | 00:02 | PASS |
- | api_check | functest | healthcheck | 03:19 | PASS |
- | snaps_health_check | functest | healthcheck | 00:46 | PASS |
- +----------------------------+------------------+---------------------+------------------+----------------+
-
-You can run functest-healcheck, functest-smoke, functest-features,
-functest-components and functest-vnf.
-
-The result tables show the results by test case, it can be::
-
- * PASS
- * FAIL
- * SKIP: if the scenario/installer does not support the test case
-
-
-Manual run
-==========
-If you want to run the test step by step, you may add docker option then run
-the different commands within the docker.
-
-Considering the healthcheck example, running functest manaully means::
-
- sudo docker run -ti --env-file env \
- -v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
- -v $(pwd)/images:/home/opnfv/functest/images \
- opnfv/functest-healthcheck /bin/bash
-
-The docker prompt shall be returned. Then within the docker run the following
-commands::
-
- $ source /home/opnfv/functest/conf/env_file
-
-Tier
-----
-Each Alpine container provided on the docker hub matches with a tier.
-The following commands are available::
-
- # functest tier list
- - 0. healthcheck:
- ['connection_check', 'api_check', 'snaps_health_check']
- # functest tier show healthcheck
- +---------------------+---------------+--------------------------+-------------------------------------------------+------------------------------------+
- | TIERS | ORDER | CI LOOP | DESCRIPTION | TESTCASES |
- +---------------------+---------------+--------------------------+-------------------------------------------------+------------------------------------+
- | healthcheck | 0 | (daily)|(weekly) | First tier to be executed to verify the | connection_check api_check |
- | | | | basic operations in the VIM. | snaps_health_check |
- +---------------------+---------------+--------------------------+-------------------------------------------------+------------------------------------+
-
-To run all the cases of the tier, type::
-
- # functest tier run healthcheck
-
-Testcase
---------
-Testcases can be listed, shown and run though the CLI::
-
- # functest testcase list
- connection_check
- api_check
- snaps_health_check
- # functest testcase show api_check
- +-------------------+--------------------------------------------------+------------------+---------------------------+
- | TEST CASE | DESCRIPTION | CRITERIA | DEPENDENCY |
- +-------------------+--------------------------------------------------+------------------+---------------------------+
- | api_check | This test case verifies the retrieval of | 100 | ^((?!lxd).)*$ |
- | | OpenStack clients: Keystone, Glance, | | |
- | | Neutron and Nova and may perform some | | |
- | | simple queries. When the config value of | | |
- | | snaps.use_keystone is True, functest | | |
- | | must have access to the cloud's private | | |
- | | network. | | |
- +-------------------+--------------------------------------------------+------------------+---------------------------+
- # functest testcase run connection_check
- ...
- # functest run all
-
-You can also type run_tests -t all to run all the tests.
-
-Note the list of test cases depend on the installer and the scenario.
-
-Note that the flavors for the SNAPS test cases are able to be configured giving
-new metadata values as well as new values for the basic elements of flavor
-(i.e. ram, vcpu, disk, ephemeral, swap etc).
-The snaps.flavor_extra_specs dict in the config_functest.yaml file could be
-used for this purpose.
-
-Reporting results to the test Database
-======================================
-In OPNFV CI we collect all the results from CI. A test API shall be available
-as well as a test database `[16]`_.
-
-
-.. _`[16]`: http://testresults.opnfv.org/test/
diff --git a/docs/testing/user/userguide/test_details.rst b/docs/testing/user/userguide/test_details.rst
index 53078ea8b..98247d488 100644
--- a/docs/testing/user/userguide/test_details.rst
+++ b/docs/testing/user/userguide/test_details.rst
@@ -24,25 +24,10 @@ The tests are:
* *connection_check*
- * *api_check*
- * *snaps_health_check*
-Connection_check consists in 9 test cases (test duration < 5s) checking the
+Connection_check consists in test cases (test duration < 5s) checking the
connectivity with Glance, Keystone, Neutron, Nova and the external network.
-Api_check verifies the retrieval of OpenStack clients: Keystone, Glance,
-Neutron and Nova and may perform some simple queries. When the config value of
-snaps.use_keystone is True, functest must have access to the cloud's private
-network. This suite consists in 49 tests (test duration < 2 minutes).
-
-Snaps_health_check creates a VM with a single port with an IPv4 address that
-is assigned by DHCP and then validates the expected IP with the actual.
-
-The flavors for the SNAPS test cases are able to be configured giving new
-metadata values as well as new values for the basic elements of flavor (i.e.
-ram, vcpu, disk, ephemeral, swap etc). The snaps.flavor_extra_specs dict in the
-config_functest.yaml file could be used for this purpose.
-
Self-obviously, successful completion of the 'healthcheck' testcase is a
necessary pre-requisite for the execution of all other test Tiers.
@@ -228,21 +213,6 @@ NOTE: Test case 'rally_sanity' executes a limited number of Rally smoke test
cases. Test case 'rally_full' executes the full defined set of Rally tests.
-snaps_smoke
-------------
-
-This test case contains tests that setup and destroy environments with VMs with
-and without Floating IPs with a newly created user and project. Set the config
-value snaps.use_floating_ips (True|False) to toggle this functionality.
-Please note that When the configuration value of snaps.use_keystone is True,
-Functest must have access the cloud's private network.
-This suite consists in 120 tests (test duration ~= 50 minutes)
-
-The flavors for the SNAPS test cases are able to be configured giving new
-metadata values as well as new values for the basic elements of flavor (i.e.
-ram, vcpu, disk, ephemeral, swap etc). The snaps.flavor_extra_specs dict in
-the config_functest.yaml file could be used for this purpose.
-
SDN Controllers
---------------
@@ -302,53 +272,6 @@ Note: the checks in OpenDaylight are based on the returned HTTP status
code returned by OpenDaylight.
-Features
---------
-
-Functest has been supporting several feature projects since Brahmaputra:
-
-
-+-----------------+---------+----------+--------+-----------+-----------+
-| Test | Brahma | Colorado | Danube | Euphrates | Fraser |
-+=================+=========+==========+========+===========+===========+
-| barometer | | | X | X | X |
-+-----------------+---------+----------+--------+-----------+-----------+
-| bgpvpn | | X | X | X | X |
-+-----------------+---------+----------+--------+-----------+-----------+
-| copper | | X | | | |
-+-----------------+---------+----------+--------+-----------+-----------+
-| doctor | X | X | X | X | X |
-+-----------------+---------+----------+--------+-----------+-----------+
-| domino | | X | X | X | |
-+-----------------+---------+----------+--------+-----------+-----------+
-| fds | | | X | X | X |
-+-----------------+---------+----------+--------+-----------+-----------+
-| moon | | X | | | |
-+-----------------+---------+----------+--------+-----------+-----------+
-| multisite | | X | X | | |
-+-----------------+---------+----------+--------+-----------+-----------+
-| netready | | | X | | |
-+-----------------+---------+----------+--------+-----------+-----------+
-| odl_sfc | | X | X | X | X |
-+-----------------+---------+----------+--------+-----------+-----------+
-| opera | | | X | | |
-+-----------------+---------+----------+--------+-----------+-----------+
-| orchestra | | | X | X | X |
-+-----------------+---------+----------+--------+-----------+-----------+
-| parser | | | X | X | X |
-+-----------------+---------+----------+--------+-----------+-----------+
-| promise | X | X | X | X | X |
-+-----------------+---------+----------+--------+-----------+-----------+
-| security_scan | | X | X | | |
-+-----------------+---------+----------+--------+-----------+-----------+
-| clover | | | | | X |
-+-----------------+---------+----------+--------+-----------+-----------+
-| stor4nfv | | | | | X |
-+-----------------+---------+----------+--------+-----------+-----------+
-
-Please refer to the dedicated feature user guides for details.
-
-
VNF
---
@@ -475,15 +398,15 @@ The kubernetes testcases are distributed across various Tiers:
designed to be run with no cloud provider configured.
-.. _`[2]`: http://docs.openstack.org/developer/tempest/overview.html
-.. _`[3]`: https://rally.readthedocs.org/en/latest/index.html
+.. _`[2]`: https://docs.openstack.org/tempest/latest/
+.. _`[3]`: https://rally.readthedocs.io/en/latest/index.html
.. _`[5]`: https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater/blob/master/openstack-blueprint.yaml
.. _`[8]`: https://github.com/openstack/refstack-client
-.. _`[9]`: https://github.com/openstack/defcore
+.. _`[9]`: https://github.com/openstack/interop
.. _`[10]`: https://github.com/openstack/interop/blob/master/2016.08/procedure.rst
-.. _`[11]`: http://robotframework.org/
-.. _`[13]`: https://wiki.opnfv.org/display/PROJ/SNAPS-OO
+.. _`[11]`: https://robotframework.org/
+.. _`[13]`: https://git.opnfv.org/snaps/
.. _`[14]`: https://github.com/oolorg/opnfv-functest-vrouter
-.. _`[15]`: https://www.rebaca.com/abot-test-orchestration-tool/
-.. _`[16]`: https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-tests.md
+.. _`[15]`: https://github.com/RebacaInc/abot_charm
+.. _`[16]`: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-testing/e2e-tests.md
.. _`[17]`: https://github.com/Metaswitch/clearwater-heat/blob/release-129/clearwater.yaml
diff --git a/docs/testing/user/userguide/test_overview.rst b/docs/testing/user/userguide/test_overview.rst
index 4240bf3cd..bc3e79dcb 100644
--- a/docs/testing/user/userguide/test_overview.rst
+++ b/docs/testing/user/userguide/test_overview.rst
@@ -11,27 +11,19 @@ infrastructure.
The current list of test suites can be distributed over 5 main domains:
* VIM (Virtualised Infrastructure Manager)
* Controllers (i.e. SDN Controllers)
- * Features
* VNF (Virtual Network Functions)
* Kubernetes
Functest test suites are also distributed in the OPNFV testing categories:
-healthcheck, smoke, features, components, performance, VNF, Stress tests.
+healthcheck, smoke, benchmarking, VNF, Stress tests.
-All the Healthcheck and smoke tests of a given scenario must be succesful to
+All the Healthcheck and smoke tests of a given scenario must be successful to
validate the scenario for the release.
+-------------+---------------+------------+----------------------------------+
| Domain | Tier | Test case | Comments |
+=============+===============+============+==================================+
| VIM | healthcheck | connection | Check OpenStack connectivity |
-| | | \_check | through SNAPS framework |
-| | +------------+----------------------------------+
-| | | api_check | Check OpenStack API through |
-| | | | SNAPS framework |
-| | +------------+----------------------------------+
-| | | snaps | basic instance creation, check |
-| | | \_health | DHCP |
| | | \_check | |
| +---------------+------------+----------------------------------+
| | smoke | vping_ssh | NFV "Hello World" using an SSH |
@@ -62,9 +54,6 @@ validate the scenario for the release.
| | | rally | Run a subset of the OpenStack |
| |  | \_sanity | Rally Test Suite in smoke mode |
| | +------------+----------------------------------+
-| | | snaps\ | Run the SNAPS-OO integration |
-| |  | \_smoke | tests |
-| | +------------+----------------------------------+
| | | refstack | Reference RefStack suite |
| | | \_defcore | tempest selection for NFV |
| | +------------+----------------------------------+
@@ -98,48 +87,10 @@ validate the scenario for the release.
| | | | upstream testcases. See below |
| | | | for details |
+-------------+---------------+------------+----------------------------------+
-| Features | features | bgpvpn | Implementation of the OpenStack |
-| | | | bgpvpn API from the SDNVPN |
-| | | | feature project. It allows for |
-| | | | the creation of BGP VPNs. |
-| | | | See `SDNVPN User Guide`_ for |
-| | | | details |
-| | +------------+----------------------------------+
-| | | doctor | Doctor platform, as of Colorado |
-| | | | release, provides the three |
-| | | | features: |
-| | | | * Immediate Notification |
-| | | | * Consistent resource state |
-| | | | awareness for compute host down |
-| | | | * Valid compute host status |
-| | | | given to VM owner |
-| | | | See `Doctor User Guide`_ for |
-| | | | details |
-| | +------------+----------------------------------+
-| | | odl-sfc | SFC testing for odl scenarios |
-| | | | See `SFC User Guide`_ for details|
-| | +------------+----------------------------------+
-| | | parser | Parser is an integration project |
-| | | | which aims to provide |
-| | | | placement/deployment templates |
-| | | | translation for OPNFV platform, |
-| | | | including TOSCA -> HOT, POLICY ->|
-| | | | TOSCA and YANG -> TOSCA. it |
-| | | | deals with a fake vRNC. |
-| | | | See `Parser User Guide`_ for |
-| | | | details |
-| | +------------+----------------------------------+
-| | | fds | Test Suite for the OpenDaylight |
-| | | | SDN Controller when the GBP |
-| | | | features are installed. It |
-| | | | integrates some test suites from |
-| | | | upstream using Robot as the test |
-| | | | framework |
-+-------------+---------------+------------+----------------------------------+
| VNF | vnf | cloudify | Example of a real VNF deployment |
| | | \_ims | to show the NFV capabilities of |
| | | | the platform. The IP Multimedia |
-| | | | Subsytem is a typical Telco test |
+| | | | Subsystem is a typical Telco test|
| | | | case, referenced by ETSI. |
| | | | It provides a fully functional |
| | | | VoIP System |
@@ -164,13 +115,6 @@ validate the scenario for the release.
| | smoke | k8s\_ | Run a subset of Kubernetes |
| | | conformance| End-to-End tests, expected to |
| | | | pass on any Kubernetes cluster |
-| +---------------+------------+----------------------------------+
-| | stor4nfv | stor4nfv | Run tests necessary to |
-| | | \_k8s | demonstrate conformance of the |
-| | | | K8s+Stor4NFV deployment |
-| +---------------+------------+----------------------------------+
-| | clover | clover_k8s | Test functionality of |
-| | | | K8s+Istio+Clover deployment. |
+-------------+---------------+------------+----------------------------------+
@@ -193,7 +137,7 @@ An overview of the Functest Structural Concept is depicted graphically below:
Some of the test cases are developed by Functest team members, whereas others
are integrated from upstream communities or other OPNFV projects. For example,
-`Tempest <http://docs.openstack.org/developer/tempest/overview.html>`_ is the
+`Tempest <https://docs.openstack.org/tempest/latest/>`_ is the
OpenStack integration test suite and Functest is in charge of the selection,
integration and automation of those tests that fit suitably to OPNFV.
@@ -229,12 +173,11 @@ combinations (which may change from one version to another):
Most of the tests are runnable by any combination, but some tests might have
restrictions imposed by the utilized installers or due to the available
-deployed features. The system uses the environment variables (INSTALLER_TYPE
-and DEPLOY_SCENARIO) to automatically determine the valid test cases, for each
-given environment.
+deployed services. The system uses the environment variables to automatically
+determine the valid test cases, for each given environment.
A convenience Functest CLI utility is also available to simplify setting up the
-Functest evironment, management of the OpenStack environment (e.g. resource
+Functest environment, management of the OpenStack environment (e.g. resource
clean-up) and for executing tests.
The Functest CLI organised the testcase into logical Tiers, which contain in
turn one or more testcases. The CLI allows execution of a single specified
@@ -242,10 +185,6 @@ testcase, all test cases in a specified Tier, or the special case of execution
of **ALL** testcases. The Functest CLI is introduced in more details in next
section.
-.. _`[2]`: http://docs.openstack.org/developer/tempest/overview.html
-.. _`[3]`: https://rally.readthedocs.org/en/latest/index.html
-.. _`Doctor User Guide`: http://artifacts.opnfv.org/doctor/colorado/userguide/index.html
-.. _`SDNVPN User Guide`: http://artifacts.opnfv.org/sdnvpn/colorado/docs/userguide/index.html
-.. _`Parser User Guide`: http://artifacts.opnfv.org/parser/colorado/docs/userguide/index.html
+.. _`[2]`: https://docs.openstack.org/tempest/latest/
+.. _`[3]`: https://rally.readthedocs.io/en/latest/index.html
.. _`Functest Dashboard`: http://testresults.opnfv.org/
-.. _`SFC User Guide`: http://artifacts.opnfv.org/sfc/colorado/userguide/index.html
diff --git a/docs/testing/user/userguide/test_results.rst b/docs/testing/user/userguide/test_results.rst
index bb28989ae..10f87d8ec 100644
--- a/docs/testing/user/userguide/test_results.rst
+++ b/docs/testing/user/userguide/test_results.rst
@@ -10,7 +10,7 @@ In manual mode test results are displayed in the console and result files
are put in /home/opnfv/functest/results.
If you want additional logs, you may configure the logging.ini under
-/usr/lib/python2.7/site-packages/xtesting/ci.
+/usr/lib/python3.8/site-packages/xtesting/ci.
Automated testing
-----------------
@@ -21,104 +21,143 @@ end of each suite and can be described as follow.
Healthcheck suite::
- +----------------------------+------------------+---------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +----------------------------+------------------+---------------------+------------------+----------------+
- | connection_check | functest | healthcheck | 00:07 | PASS |
- | api_check | functest | healthcheck | 07:46 | PASS |
- | snaps_health_check | functest | healthcheck | 00:36 | PASS |
- +----------------------------+------------------+---------------------+------------------+----------------+
+ +--------------------------+------------------+---------------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +--------------------------+------------------+---------------------+------------------+----------------+
+ | connection_check | functest | healthcheck | 00:03 | PASS |
+ | tenantnetwork1 | functest | healthcheck | 00:05 | PASS |
+ | tenantnetwork2 | functest | healthcheck | 00:06 | PASS |
+ | vmready1 | functest | healthcheck | 00:06 | PASS |
+ | vmready2 | functest | healthcheck | 00:08 | PASS |
+ | singlevm1 | functest | healthcheck | 00:32 | PASS |
+ | singlevm2 | functest | healthcheck | 00:37 | PASS |
+ | vping_ssh | functest | healthcheck | 00:46 | PASS |
+ | vping_userdata | functest | healthcheck | 00:39 | PASS |
+ | cinder_test | functest | healthcheck | 01:05 | PASS |
+ | tempest_smoke | functest | healthcheck | 05:39 | PASS |
+ | tempest_horizon | functest | healthcheck | 01:05 | PASS |
+ | odl | functest | healthcheck | 00:00 | SKIP |
+ +--------------------------+------------------+---------------------+------------------+----------------+
Smoke suite::
- +------------------------------+------------------+---------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +------------------------------+------------------+---------------+------------------+----------------+
- | vping_ssh | functest | smoke | 00:57 | PASS |
- | vping_userdata | functest | smoke | 00:33 | PASS |
- | tempest_smoke_serial | functest | smoke | 13:22 | PASS |
- | rally_sanity | functest | smoke | 24:07 | PASS |
- | refstack_defcore | functest | smoke | 05:21 | PASS |
- | patrole | functest | smoke | 04:29 | PASS |
- | snaps_smoke | functest | smoke | 46:54 | PASS |
- | odl | functest | smoke | 00:00 | SKIP |
- | neutron_trunk | functest | smoke | 00:00 | SKIP |
- +------------------------------+------------------+---------------+------------------+----------------+
-
-Features suite::
-
- +-----------------------------+------------------------+------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +-----------------------------+------------------------+------------------+------------------+----------------+
- | doctor-notification | doctor | features | 00:00 | SKIP |
- | bgpvpn | sdnvpn | features | 00:00 | SKIP |
- | functest-odl-sfc | sfc | features | 00:00 | SKIP |
- | barometercollectd | barometer | features | 00:00 | SKIP |
- | fds | fastdatastacks | features | 00:00 | SKIP |
- +-----------------------------+------------------------+------------------+------------------+----------------+
-
-Components suite::
-
- +-------------------------------+------------------+--------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +-------------------------------+------------------+--------------------+------------------+----------------+
- | tempest_full_parallel | functest | components | 48:28 | PASS |
- | rally_full | functest | components | 126:02 | PASS |
- +-------------------------------+------------------+--------------------+------------------+----------------+
+ +---------------------------+------------------+---------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +---------------------------+------------------+---------------+------------------+----------------+
+ | tempest_neutron | functest | smoke | 15:30 | PASS |
+ | tempest_cinder | functest | smoke | 02:01 | PASS |
+ | tempest_keystone | functest | smoke | 01:17 | PASS |
+ | tempest_heat | functest | smoke | 22:14 | PASS |
+ | tempest_telemetry | functest | smoke | 00:00 | SKIP |
+ | rally_sanity | functest | smoke | 17:24 | PASS |
+ | refstack_compute | functest | smoke | 07:03 | PASS |
+ | refstack_object | functest | smoke | 02:09 | PASS |
+ | refstack_platform | functest | smoke | 07:31 | PASS |
+ | tempest_full | functest | smoke | 41:52 | PASS |
+ | tempest_scenario | functest | smoke | 08:42 | PASS |
+ | tempest_slow | functest | smoke | 43:42 | PASS |
+ | patrole_admin | functest | smoke | 21:06 | PASS |
+ | patrole_member | functest | smoke | 21:23 | PASS |
+ | patrole_reader | functest | smoke | 21:56 | PASS |
+ | tempest_barbican | functest | smoke | 02:30 | PASS |
+ | tempest_octavia | functest | smoke | 00:00 | SKIP |
+ | tempest_cyborg | functest | smoke | 00:00 | SKIP |
+ +---------------------------+------------------+---------------+------------------+----------------+
+
+Smoke CNTT suite::
+
+ +-------------------------------+------------------+---------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +-------------------------------+------------------+---------------+------------------+----------------+
+ | tempest_neutron_cntt | functest | smoke | 11:35 | PASS |
+ | tempest_cinder_cntt | functest | smoke | 01:58 | PASS |
+ | tempest_keystone_cntt | functest | smoke | 01:13 | PASS |
+ | tempest_heat_cntt | functest | smoke | 22:32 | PASS |
+ | rally_sanity_cntt | functest | smoke | 17:16 | PASS |
+ | tempest_full_cntt | functest | smoke | 41:13 | PASS |
+ | tempest_scenario_cntt | functest | smoke | 08:57 | PASS |
+ | tempest_slow_cntt | functest | smoke | 35:58 | PASS |
+ +-------------------------------+------------------+---------------+------------------+----------------+
+
+Benchmarking suite::
+
+ +--------------------+------------------+----------------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +--------------------+------------------+----------------------+------------------+----------------+
+ | rally_full | functest | benchmarking | 93:03 | PASS |
+ | rally_jobs | functest | benchmarking | 27:05 | PASS |
+ | vmtp | functest | benchmarking | 17:56 | PASS |
+ | shaker | functest | benchmarking | 24:02 | PASS |
+ +--------------------+------------------+----------------------+------------------+----------------+
+
+Benchmarking CNTT suite::
+
+ +-------------------------+------------------+----------------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +-------------------------+------------------+----------------------+------------------+----------------+
+ | rally_full_cntt | functest | benchmarking | 89:52 | PASS |
+ | rally_jobs_cntt | functest | benchmarking | 19:39 | PASS |
+ | vmtp | functest | benchmarking | 16:59 | PASS |
+ | shaker | functest | benchmarking | 23:43 | PASS |
+ +-------------------------+------------------+----------------------+------------------+----------------+
Vnf suite::
- +----------------------+------------------+--------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +----------------------+------------------+--------------+------------------+----------------+
- | cloudify_ims | functest | vnf | 28:15 | PASS |
- | vyos_vrouter | functest | vnf | 17:59 | PASS |
- | juju_epc | functest | vnf | 46:44 | PASS |
- +----------------------+------------------+--------------+------------------+----------------+
-
-Parser testcase::
-
- +-----------------------+-----------------+------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +-----------------------+-----------------+------------------+------------------+----------------+
- | parser-basics | parser | features | 00:00 | SKIP |
- +-----------------------+-----------------+------------------+------------------+----------------+
-
-Functest Kubernetes test result::
-
- +--------------------------------------+------------------------------------------------------------+
- | ENV VAR | VALUE |
- +--------------------------------------+------------------------------------------------------------+
- | INSTALLER_TYPE | compass |
- | DEPLOY_SCENARIO | k8-nosdn-nofeature-ha |
- | BUILD_TAG | jenkins-functest-compass-baremetal-daily-master-75 |
- | CI_LOOP | daily |
- +--------------------------------------+------------------------------------------------------------+
+ +----------------------+------------------+--------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +----------------------+------------------+--------------+------------------+----------------+
+ | cloudify | functest | vnf | 05:08 | PASS |
+ | cloudify_ims | functest | vnf | 24:46 | PASS |
+ | heat_ims | functest | vnf | 33:12 | PASS |
+ | vyos_vrouter | functest | vnf | 15:53 | PASS |
+ | juju_epc | functest | vnf | 27:52 | PASS |
+ +----------------------+------------------+--------------+------------------+----------------+
Kubernetes healthcheck suite::
- +-------------------+------------------+---------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +-------------------+------------------+---------------------+------------------+----------------+
- | k8s_smoke | functest | healthcheck | 01:54 | PASS |
- +-------------------+------------------+---------------------+------------------+----------------+
+ +-------------------+------------------+---------------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +-------------------+------------------+---------------------+------------------+----------------+
+ | k8s_quick | functest | healthcheck | 00:18 | PASS |
+ | k8s_smoke | functest | healthcheck | 01:14 | PASS |
+ +-------------------+------------------+---------------------+------------------+----------------+
Kubernetes smoke suite::
- +-------------------------+------------------+---------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +-------------------------+------------------+---------------+------------------+----------------+
- | k8s_conformance | functest | smoke | 57:47 | PASS |
- +-------------------------+------------------+---------------+------------------+----------------+
-
-Kubernetes features suite::
-
- +----------------------+------------------+------------------+------------------+----------------+
- | TEST CASE | PROJECT | TIER | DURATION | RESULT |
- +----------------------+------------------+------------------+------------------+----------------+
- | stor4nfv_k8s | stor4nfv | stor4nfv | 00:00 | SKIP |
- | clover_k8s | clover | clover | 00:00 | SKIP |
- +----------------------+------------------+------------------+------------------+----------------+
+ +---------------------------+------------------+---------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +---------------------------+------------------+---------------+------------------+----------------+
+ | k8s_conformance | functest | smoke | 94:26 | PASS |
+ | xrally_kubernetes | functest | smoke | 13:05 | PASS |
+ +---------------------------+------------------+---------------+------------------+----------------+
+
+Kubernetes security suite::
+
+ +---------------------------+------------------+------------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +---------------------------+------------------+------------------+------------------+----------------+
+ | kube_hunter | functest | security | 00:19 | PASS |
+ | kube_bench_master | functest | security | 00:02 | PASS |
+ | kube_bench_node | functest | security | 00:01 | PASS |
+ +---------------------------+------------------+------------------+------------------+----------------+
+
+Kubernetes benchmarking suite::
+
+ +--------------------------------+------------------+----------------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +--------------------------------+------------------+----------------------+------------------+----------------+
+ | xrally_kubernetes_full | functest | benchmarking | 34:16 | PASS |
+ +--------------------------------+------------------+----------------------+------------------+----------------+
+
+Kubernetes cnf suite::
+
+ +-------------------------+------------------+--------------+------------------+----------------+
+ | TEST CASE | PROJECT | TIER | DURATION | RESULT |
+ +-------------------------+------------------+--------------+------------------+----------------+
+ | k8s_vims | functest | cnf | 09:06 | PASS |
+ | helm_vims | functest | cnf | 08:54 | PASS |
+ | cnf_conformance | functest | cnf | 02:00 | PASS |
+ +-------------------------+------------------+--------------+------------------+----------------+
Results are automatically pushed to the test results database, some additional
result files are pushed to OPNFV artifact web sites.
diff --git a/docs/testing/user/userguide/troubleshooting.rst b/docs/testing/user/userguide/troubleshooting.rst
index 5755544e6..d857ed4c4 100644
--- a/docs/testing/user/userguide/troubleshooting.rst
+++ b/docs/testing/user/userguide/troubleshooting.rst
@@ -44,8 +44,8 @@ follows::
The Functest CLI is designed to route a call to the corresponding internal
python scripts, located in paths::
- /usr/lib/python2.7/site-packages/functest/opnfv_tests/openstack/vping/vping_ssh.py
- /usr/lib/python2.7/site-packages/functest/opnfv_tests/openstack/vping/vping_userdata.py
+ /usr/lib/python3.8/site-packages/functest/opnfv_tests/openstack/vping/vping_ssh.py
+ /usr/lib/python3.8/site-packages/functest/opnfv_tests/openstack/vping/vping_userdata.py
Notes:
@@ -102,7 +102,7 @@ In this case, proceed to create it manually. These are some hints::
--protocol tcp --port-range-min 80 --port-range-max 80 --remote-ip-prefix 0.0.0.0/0
The next step is to create the instances. The image used is located in
-*/home/opnfv/functest/data/cirros-0.4.0-x86_64-disk.img* and a Glance image is
+*/home/opnfv/functest/data/cirros-0.5.1-x86_64-disk.img* and a Glance image is
created with the name **functest-vping**. If booting the instances fails (i.e.
the status is not **ACTIVE**), you can check why it failed by doing::
@@ -125,7 +125,7 @@ This test case creates a floating IP on the external network and assigns it to
the second instance **opnfv-vping-2**. The purpose of this is to establish
a SSH connection to that instance and SCP a script that will ping the first
instance. This script is located in the repository under
-/usr/lib/python2.7/site-packages/functest/opnfv_tests/openstack/vping/ping.sh
+/usr/lib/python3.8/site-packages/functest/opnfv_tests/openstack/vping/ping.sh
and takes an IP as a parameter. When the SCP is completed, the test will do a
SSH call to that script inside the second instance. Some problems can happen
here::
@@ -133,8 +133,8 @@ here::
vPing_ssh- ERROR - Cannot establish connection to IP xxx.xxx.xxx.xxx. Aborting
If this is displayed, stop the test or wait for it to finish, if you have used
-the special method of test invocation with specific supression of OpenStack
-resource clean-up, as explained earler. It means that the Container can not
+the special method of test invocation with specific suppression of OpenStack
+resource clean-up, as explained earlier. It means that the Container can not
reach the Public/External IP assigned to the instance **opnfv-vping-2**. There
are many possible reasons, and they really depend on the chosen scenario. For
most of the ODL-L3 and ONOS scenarios this has been noticed and it is a known
@@ -158,7 +158,7 @@ container::
ping <public IP>
If the ping does not return anything, try to ping from the Host where the
-Docker container is running. If that solves the problem, check the iptable
+Docker container is running. If that solves the problem, check the iptables
rules because there might be some rules rejecting ICMP or TCP traffic
coming/going from/to the container.
@@ -258,42 +258,30 @@ debug information can be found from tempest.log file stored into related Rally
deployment folder.
Functest offers a possibility to test a customized list of Tempest test cases.
-To enable that, add a new entry in docker/components/testcases.yaml on the
-"components" container with the following content::
-
- -
- case_name: tempest_custom
- project_name: functest
- criteria: 100
- blocking: false
- description: >-
- The test case allows running a customized list of tempest
- test cases
- dependencies:
- installer: ''
- scenario: ''
- run:
- module: 'functest.opnfv_tests.openstack.tempest.tempest'
- class: 'TempestCustom'
-
-Also, a list of the Tempest test cases must be provided to the container or
-modify the existing one in
-/usr/lib/python2.7/site-packages/functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt
-
-Example of custom list of tests 'my-custom-tempest-tests.txt'::
-
- tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops[compute,id-7fff3fb3-91d8-4fd0-bd7d-0204f1f180ba,network,smoke]
- tempest.scenario.test_network_basic_ops.TestNetworkBasicOps.test_network_basic_ops[compute,id-f323b3ba-82f8-4db7-8ea6-6a895869ec49,network,smoke]
+To enable that, add a new entry in docker/smoke/testcases.yaml on the
+"smoke" container with the following content::
+
+ -
+ case_name: tempest_custom
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ The test case allows running a customized list of tempest
+ test cases
+ run:
+ name: tempest_common
+ args:
+ mode: "tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops|\
+ tempest.scenario.test_network_basic_ops.TestNetworkBasicOps.test_network_basic_ops"
This is an example of running a customized list of Tempest tests in Functest::
sudo docker run --env-file env \
-v $(pwd)/openstack.creds:/home/opnfv/functest/conf/env_file \
-v $(pwd)/images:/home/opnfv/functest/images \
- -v $(pwd)/my-custom-testcases.yaml:/usr/lib/python2.7/site-packages/functest/ci/testcases.yaml \
- -v $(pwd)/my-custom-tempest-tests.txt:/usr/lib/python2.7/site-packages/functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt \
- opnfv/functest-components run_tests -t tempest_custom
-
+ -v $(pwd)/my-custom-testcases.yaml:/usr/lib/python3.8/site-packages/xtesting/ci/testcases.yaml \
+ opnfv/functest-smoke run_tests -t tempest_custom
Rally
^^^^^
@@ -314,14 +302,14 @@ Possible scenarios are:
To know more about what those scenarios are doing, they are defined in
directory:
-/usr/lib/python2.7/site-packages/functest/opnfv_tests/openstack/rally/scenario
+/usr/lib/python3.8/site-packages/functest/opnfv_tests/openstack/rally/scenario
For more info about Rally scenario definition please refer to the Rally
official documentation. `[3]`_
To check any possible problems with Rally, the logs are stored under
*/home/opnfv/functest/results/rally/* in the Functest Docker container.
-.. _`[3]`: https://rally.readthedocs.org/en/latest/index.html
+.. _`[3]`: https://rally.readthedocs.io/en/latest/index.html
Controllers
-----------
diff --git a/elements/functest/element-deps b/elements/functest/element-deps
new file mode 100644
index 000000000..d06e3d771
--- /dev/null
+++ b/elements/functest/element-deps
@@ -0,0 +1 @@
+xtestingci
diff --git a/elements/functest/install.d/16-functest b/elements/functest/install.d/16-functest
new file mode 100755
index 000000000..97d37e499
--- /dev/null
+++ b/elements/functest/install.d/16-functest
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+download-frozen-image-v2.sh /data/docker/functest \
+ opnfv/functest-healthcheck:latest \
+ opnfv/functest-smoke:latest \
+ opnfv/functest-smoke-cntt:latest \
+ opnfv/functest-benchmarking:latest \
+ opnfv/functest-benchmarking-cntt:latest \
+ opnfv/functest-vnf:latest
+mkdir -p /data/images && wget -q -O- https://git.opnfv.org/functest/plain/functest/ci/download_images.sh | sh -s -- /data/images && ls -1 /data/images/*
+git clone https://git.opnfv.org/functest /home/debian/functest
+chown -R 1000:1000 /home/debian/functest
+
+exit 0
diff --git a/functest/ci/__init__.py b/functest/ci/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/functest/ci/__init__.py
+++ /dev/null
diff --git a/functest/ci/add_proxy.sh b/functest/ci/add_proxy.sh
index 3244f246a..9d7db22e4 100644
--- a/functest/ci/add_proxy.sh
+++ b/functest/ci/add_proxy.sh
@@ -1,31 +1,84 @@
-#!/bin/bash
+#!/bin/sh
set -e
-pushd "${1:-/home/opnfv/functest/images}" > /dev/null
+initdir=$(pwd)
+cd "${1:-/home/opnfv/functest/images}"
+
+http_proxy_host=${http_proxy_host:-proxy}
+http_proxy_port=${http_proxy_port:-8080}
+
+http_proxy=http://${http_proxy_host}:${http_proxy_port}
+https_proxy=${https_proxy:-${http_proxy:-http://proxy:8080}}
+ftp_proxy=${ftp_proxy:-${http_proxy:-http://proxy:8080}}
+no_proxy=${no_proxy:-"10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"}
images=${images-"\
-cloudify-manager-premium-4.0.1.qcow2 \
ubuntu-14.04-server-cloudimg-amd64-disk1.img \
ubuntu-16.04-server-cloudimg-amd64-disk1.img"}
add_proxy () {
cat << EOF >> "$1"
-http_proxy=${http_proxy:-http://proxy:8080}
-HTTP_PROXY=${http_proxy:-http://proxy:8080}
-https_proxy=${https_proxy:-${http_proxy:-http://proxy:8080}}
-HTTPS_PROXY=${https_proxy:-${http_proxy:-http://proxy:8080}}
-ftp_proxy=${ftp_proxy:-${http_proxy:-http://proxy:8080}}
-FTP_PROXY=${ftp_proxy:-${http_proxy:-http://proxy:8080}}
-no_proxy=${no_proxy:-"10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"}
-NO_PROXY=${no_proxy:-"10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"}
+http_proxy=${http_proxy}
+HTTP_PROXY=${http_proxy}
+https_proxy=${https_proxy}
+HTTPS_PROXY=${https_proxy}
+ftp_proxy=${ftp_proxy}
+FTP_PROXY=${ftp_proxy}
+no_proxy=${no_proxy}
+NO_PROXY=${no_proxy}
EOF
}
add_proxy_apt () {
cat << EOF >> "$1"
-Acquire::http::Proxy "${http_proxy:-http://proxy:8080}";
-Acquire::https::Proxy "${https_proxy:-http://proxy:8080}";
+Acquire::http::Proxy "${http_proxy}";
+Acquire::https::Proxy "${https_proxy}";
+EOF
+}
+
+add_proxy_juju_env () {
+ cat << EOF >> "$1"
+export no_proxy="${no_proxy}";
+export NO_PROXY="${no_proxy}";
+EOF
+}
+
+add_proxy_juju_systemd () {
+ cat << EOF >> "$1"
+[Manager]
+DefaultEnvironment="no_proxy='${no_proxy}'" "NO_PROXY='${no_proxy}'"
+EOF
+}
+
+add_proxy_maven () {
+ cat << EOF >> "$1"
+<settings>
+ <proxies>
+ <proxy>
+ <id>example-proxy</id>
+ <active>true</active>
+ <protocol>http</protocol>
+ <host>"${http_proxy_host}"</host>
+ <port>"${http_proxy_port}"</port>
+ </proxy>
+ </proxies>
+</settings>
+EOF
+}
+
+add_proxy_svn () {
+ cat << EOF >> "$1"
+[global]
+http-proxy-host = "${http_proxy_host}"
+http-proxy-port = "${http_proxy_port}"
+EOF
+}
+
+add_proxy_pip () {
+ cat << EOF >> "$1"
+[global]
+proxy="${http_proxy}"
EOF
}
@@ -37,17 +90,49 @@ for image in $images; do
fi
guestmount -a "${image}" -i --rw "${tmpdir}"
add_proxy "${tmpdir}/etc/environment"
- if [[ ${image} == *"cloudify-manager"* ]]; then
- echo >> "${tmpdir}/etc/sysconfig/cloudify-mgmtworker"
- add_proxy "${tmpdir}/etc/sysconfig/cloudify-mgmtworker"
- echo >> "${tmpdir}/etc/sysconfig/cloudify-restservice"
- add_proxy "${tmpdir}/etc/sysconfig/cloudify-restservice"
- fi
- if [[ ${image} == "ubuntu"* ]]; then
+ if expr "$image" : 'ubuntu' ; then
add_proxy_apt "${tmpdir}/etc/apt/apt.conf"
+ add_proxy_juju_env "${tmpdir}/etc/juju-proxy.conf"
+ add_proxy_juju_systemd "${tmpdir}/etc/juju-proxy-systemd.conf"
+ mkdir -p ${tmpdir}/root/.m2
+ mkdir -p ${tmpdir}/root/.subversion
+ add_proxy_maven "${tmpdir}/root/.m2/settings.xml"
+ add_proxy_svn "${tmpdir}/root/.subversion/servers"
+ add_proxy_pip "${tmpdir}/etc/pip.conf"
fi
guestunmount "${tmpdir}"
done
+if [ -f cloudify-docker-manager-community-19.01.24.tar ]; then
+ sudo docker load -i cloudify-docker-manager-community-19.01.24.tar
+ dockerfile=${tmpdir}/Dockerfile
+ cat << EOF > $dockerfile
+FROM docker-cfy-manager:latest
+ENV HTTP_PROXY "${http_proxy}"
+ENV HTTPS_PROXY "${https_proxy}"
+ENV NO_PROXY "${no_proxy}"
+EOF
+ for f in /etc/sysconfig/cloudify-mgmtworker /etc/sysconfig/cloudify-restservice; do \
+ cat << EOF >> $dockerfile
+RUN echo >> $f
+RUN echo "http_proxy=${http_proxy}" >> $f
+RUN echo "https_proxy=${https_proxy}" >> $f
+RUN echo "HTTP_PROXY=${http_proxy}" >> $f
+RUN echo "HTTPS_PROXY=${https_proxy}" >> $f
+RUN echo "no_proxy=${no_proxy}" >> $f
+EOF
+ done
+ sudo docker build -t docker-cfy-manager -f $dockerfile ${tmpdir}
+ sudo docker save \
+ docker-cfy-manager > cloudify-docker-manager-community-19.01.24.tar
+ sudo docker rmi docker-cfy-manager
+
+ rm "${dockerfile}"
+else
+ echo "skip cloudify-docker-manager-community-19.01.24.tar \
+ ($(pwd)/cloudify-docker-manager-community-19.01.24.tar not found)"
+fi
+
rmdir "${tmpdir}"
-popd > /dev/null
+cd initdir
+
diff --git a/functest/ci/check_deployment.py b/functest/ci/check_deployment.py
deleted file mode 100644
index 16c69345c..000000000
--- a/functest/ci/check_deployment.py
+++ /dev/null
@@ -1,188 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2017 Ericsson and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-
-""" OpenStack deployment checker
-
-Verifies that:
-
- - Credentials file is given and contains the right information
- - OpenStack endpoints are reachable
-"""
-
-import logging
-import logging.config
-import os
-import socket
-
-import pkg_resources
-from six.moves import urllib
-from snaps.openstack.tests import openstack_tests
-from snaps.openstack.utils import glance_utils
-from snaps.openstack.utils import keystone_utils
-from snaps.openstack.utils import neutron_utils
-from snaps.openstack.utils import nova_utils
-
-from functest.utils import constants
-from functest.opnfv_tests.openstack.snaps import snaps_utils
-
-__author__ = "Jose Lausuch <jose.lausuch@ericsson.com>"
-
-LOGGER = logging.getLogger(__name__)
-
-
-def verify_connectivity(endpoint):
- """ Returns true if an hostname/port is reachable"""
- try:
- connection = socket.socket()
- connection.settimeout(10)
- url = urllib.parse.urlparse(endpoint)
- port = url.port
- if not port:
- port = 443 if url.scheme == "https" else 80
- connection.connect((url.hostname, port))
- LOGGER.debug('%s:%s is reachable!', url.hostname, port)
- return True
- except socket.error:
- LOGGER.error('%s:%s is not reachable.', url.hostname, port)
- except Exception: # pylint: disable=broad-except
- LOGGER.exception(
- 'Errors when verifying connectivity to %s:%s', url.hostname, port)
- return False
-
-
-def get_auth_token(os_creds):
- """ Get auth token """
- sess = keystone_utils.keystone_session(os_creds)
- try:
- return sess.get_token()
- except Exception as error:
- LOGGER.error("Got token ...FAILED")
- raise error
-
-
-class CheckDeployment(object):
- """ Check deployment class."""
-
- def __init__(self, rc_file=constants.ENV_FILE):
- self.rc_file = rc_file
- self.services = ('compute', 'network', 'image')
- self.os_creds = None
-
- def check_rc(self):
- """ Check if RC file exists and contains OS_AUTH_URL """
- if not os.path.isfile(self.rc_file):
- raise IOError('RC file {} does not exist!'.format(self.rc_file))
- if 'OS_AUTH_URL' not in open(self.rc_file).read():
- raise SyntaxError('OS_AUTH_URL not defined in {}.'.
- format(self.rc_file))
-
- def check_auth_endpoint(self):
- """ Verifies connectivity to the OS_AUTH_URL given in the RC file
- and get auth token"""
- rc_endpoint = self.os_creds.auth_url
- if not verify_connectivity(rc_endpoint):
- raise Exception("OS_AUTH_URL {} is not reachable.".
- format(rc_endpoint))
- LOGGER.info("Connectivity to OS_AUTH_URL %s ...OK", rc_endpoint)
- if get_auth_token(self.os_creds):
- LOGGER.info("Got token ...OK")
-
- def check_public_endpoint(self):
- """ Gets the public endpoint and verifies connectivity to it """
- public_endpoint = keystone_utils.get_endpoint(self.os_creds,
- 'identity',
- interface='public')
- if not verify_connectivity(public_endpoint):
- raise Exception("Public endpoint {} is not reachable.".
- format(public_endpoint))
- LOGGER.info("Connectivity to the public endpoint %s ...OK",
- public_endpoint)
-
- def check_service_endpoint(self, service):
- """ Verifies connectivity to a given openstack service """
- endpoint = keystone_utils.get_endpoint(self.os_creds,
- service,
- interface='public')
- if not verify_connectivity(endpoint):
- raise Exception("{} endpoint {} is not reachable.".
- format(service, endpoint))
- LOGGER.info("Connectivity to endpoint '%s' %s ...OK",
- service, endpoint)
-
- def check_nova(self):
- """ checks that a simple nova operation works """
- try:
- client = nova_utils.nova_client(self.os_creds)
- client.servers.list()
- LOGGER.info("Nova service ...OK")
- except Exception as error:
- LOGGER.error("Nova service ...FAILED")
- raise error
-
- def check_neutron(self):
- """ checks that a simple neutron operation works """
- try:
- client = neutron_utils.neutron_client(self.os_creds)
- client.list_networks()
- LOGGER.info("Neutron service ...OK")
- except Exception as error:
- LOGGER.error("Neutron service ...FAILED")
- raise error
-
- def check_glance(self):
- """ checks that a simple glance operation works """
- try:
- client = glance_utils.glance_client(self.os_creds)
- client.images.list()
- LOGGER.info("Glance service ...OK")
- except Exception as error:
- LOGGER.error("Glance service ...FAILED")
- raise error
-
- def check_ext_net(self):
- """ checks if external network exists """
- ext_net = snaps_utils.get_ext_net_name(self.os_creds)
- if ext_net:
- LOGGER.info("External network found: %s", ext_net)
- else:
- raise Exception("ERROR: No external networks in the deployment.")
-
- def check_all(self):
- """
- Calls all the class functions and returns 0 if all of them succeed.
- This is the method called by CLI
- """
- self.check_rc()
- try:
- self.os_creds = openstack_tests.get_credentials(
- os_env_file=self.rc_file,
- proxy_settings_str=None,
- ssh_proxy_cmd=None)
- except:
- raise Exception("Problem while getting credentials object.")
- if self.os_creds is None:
- raise Exception("Credentials is None.")
- self.check_auth_endpoint()
- self.check_public_endpoint()
- for service in self.services:
- self.check_service_endpoint(service)
- self.check_nova()
- self.check_neutron()
- self.check_glance()
- self.check_ext_net()
- return 0
-
-
-def main():
- """Entry point"""
- logging.config.fileConfig(pkg_resources.resource_filename(
- 'functest', 'ci/logging.ini'))
- logging.captureWarnings(True)
- deployment = CheckDeployment()
- return deployment.check_all()
diff --git a/functest/ci/config_aarch64_patch.yaml b/functest/ci/config_aarch64_patch.yaml
index 835a82737..278265620 100644
--- a/functest/ci/config_aarch64_patch.yaml
+++ b/functest/ci/config_aarch64_patch.yaml
@@ -1,99 +1,99 @@
---
os:
- general:
- openstack:
- image_file_name: cirros-0.4.0-aarch64-disk.img
- image_url:
- /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
vmready1:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
vmready2:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
singlevm1:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
singlevm2:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
vping_ssh:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
vping_userdata:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
cinder_test:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
tempest_smoke:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
- neutron-tempest-plugin-api:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
- refstack_defcore:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
- patrole:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
- vmtp:
- image:
- /home/opnfv/functest/images/ubuntu-14.04-server-cloudimg-arm64-uefi1.img
-
- shaker:
- image: /home/opnfv/functest/images/shaker-image-arm64.qcow2
-
- neutron_trunk:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
- networking-bgpvpn:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
- networking-sfc:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
- barbican:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_horizon:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_neutron:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_cinder:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_keystone:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_heat:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt:
+ /home/opnfv/functest/images/Fedora-Cloud-Base-30-1.2.aarch64.qcow2
+ tempest_telemetry:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ rally_sanity:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ refstack_compute:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ refstack_object:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ refstack_platform:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
tempest_full:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
tempest_scenario:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
- rally_sanity:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_slow:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ patrole:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_barbican:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_octavia:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_neutron_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_cinder_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_keystone_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_heat_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt:
+ /home/opnfv/functest/images/Fedora-Cloud-Base-30-1.2.aarch64.qcow2
+ rally_sanity_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_full_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_scenario_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ tempest_slow_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
rally_full:
- image: /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
-
- snaps:
- images:
- glance_tests:
- disk_file:
- /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- cirros:
- disk_file:
- /home/opnfv/functest/images/cirros-0.4.0-aarch64-disk.img
- ubuntu:
- disk_file:
- /home/opnfv/functest/images/ubuntu-14.04-server-cloudimg-arm64-uefi1.img
- centos:
- disk_file:
- /home/opnfv/functest/images/CentOS-7-aarch64-GenericCloud.qcow2
-
- tempest:
- use_custom_flavors: 'True'
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ rally_jobs:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ rally_full_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
+ rally_jobs_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-aarch64-disk.img
diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml
index dbea320c9..647301ab4 100644
--- a/functest/ci/config_functest.yaml
+++ b/functest/ci/config_functest.yaml
@@ -18,10 +18,10 @@ general:
rally_inst: /root/.rally
openstack:
- image_name: Cirros-0.4.0
- image_name_alt: Cirros-0.4.0-1
- image_file_name: cirros-0.4.0-x86_64-disk.img
- image_url: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.img
+ image_name: Cirros-0.5.1
+ image_name_alt: Cirros-0.5.1-1
+ image_file_name: cirros-0.5.1-x86_64-disk.img
+ image_url: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.img
image_user: cirros
image_disk_format: qcow2
image_username: cirros
@@ -42,47 +42,6 @@ general:
neutron_private_subnet_gateway: 192.168.120.254
neutron_router_name: functest-router
-snaps:
- use_keystone: 'True'
- use_floating_ips: 'True'
- flavor_extra_specs: {}
- images:
- glance_tests:
- disk_file: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.img
- cirros:
- disk_file: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.img
- ubuntu:
- disk_file:
- /home/opnfv/functest/images/ubuntu-14.04-server-cloudimg-amd64-disk1.img
- centos:
- disk_file:
- /home/opnfv/functest/images/CentOS-7-x86_64-GenericCloud.qcow2
-# netconf_override:
-# network_type: vlan
-# physical_network: physnet2
-# segmentation_id: 2366
-
-# All of these values are optional and will override the values retrieved
-# by the RC file
-# os_creds_override:
-# username: {user}
-# password: {password}
-# auth_url: {auth_url}
-# project_name: {project_name}
-# identity_api_version: {2|3}
-# network_api_version: {2}
-# compute_api_version: {2}
-# image_api_version: {1|2}
-# user_domain_id: {user_domain_id}
-# project_domain_id: {projects_domain_id}
-# interface: {interface}
-# cacert: {True|False}
-# proxy_settings:
-# host: {proxy_host}
-# port: {proxy_port}
-# ssh_proxy_cmd: {OpenSSH -o ProxyCommand value}
-
-
vping:
ping_timeout: 200
vm_flavor: m1.tiny # adapt to your environment
@@ -132,26 +91,9 @@ odl_sfc:
tempest:
verifier_name: opnfv-tempest
- identity:
- tenant_name: tempest
- tenant_description: Tenant for Tempest test suite
- user_name: tempest
- user_password: Tempest123!
- validation:
- ssh_timeout: 130
- object_storage:
- operator_role: SwiftOperator
- # network_type: vlan
- # physical_network: physnet2
- # segmentation_id: 2366
- private_net_name: tempest-net
- private_subnet_name: tempest-subnet
- private_subnet_cidr: 192.168.150.0/24
- router_name: tempest-router
rally:
deployment_name: opnfv-rally
- network_name: rally-net
vnf:
juju_epc:
diff --git a/functest/ci/config_patch.yaml b/functest/ci/config_patch.yaml
index 42220832e..d5335c3ab 100644
--- a/functest/ci/config_patch.yaml
+++ b/functest/ci/config_patch.yaml
@@ -1,10 +1,160 @@
---
+gsma:
+ tempest_smoke:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_horizon:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_neutron:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_cinder:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_keystone:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_heat:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_telemetry:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ rally_sanity:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ refstack_compute:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ refstack_object:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ refstack_platform:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_full:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_scenario:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_slow:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ patrole:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_barbican:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_octavia:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_neutron_cntt:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_cinder_cntt:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_keystone_cntt:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_heat_cntt:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ rally_sanity_cntt:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_full_cntt:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_scenario_cntt:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ tempest_slow_cntt:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ rally_full:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ rally_jobs:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ vmtp:
+ flavor_ram: 2048
+ flavor_vcpus: 1
+ flavor_disk: 40
+ shaker:
+ flavor_ram: 2048
+ flavor_vcpus: 1
+ flavor_disk: 40
+ rally_full_cntt:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ rally_jobs_cntt:
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ cloudify:
+ flavor_ram: 4096
+ flavor_vcpus: 2
+ flavor_disk: 40
+ cloudify_ims:
+ flavor_ram: 4096
+ flavor_vcpus: 2
+ flavor_disk: 40
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ heat_ims:
+ flavor_ram: 2048
+ flavor_vcpus: 1
+ flavor_disk: 40
+ vyos_vrouter:
+ flavor_ram: 4096
+ flavor_vcpus: 2
+ flavor_disk: 40
+ flavor_alt_ram: 2048
+ flavor_alt_vcpus: 1
+ flavor_alt_disk: 40
+ juju_epc:
+ flavor_ram: 2048
+ flavor_vcpus: 1
+ flavor_disk: 40
+ flavor_alt_ram: 4096
+ flavor_alt_vcpus: 2
+ flavor_alt_disk: 40
+
fdio:
- general:
- openstack:
- flavor_ram: 1024
- snaps:
- flavor_extra_specs: {'hw:mem_page_size':'large'}
vmready1:
flavor_ram: 1024
vmready2:
@@ -21,39 +171,68 @@ fdio:
flavor_ram: 1024
tempest_smoke:
flavor_ram: 1024
- neutron-tempest-plugin-api:
+ tempest_horizon:
flavor_ram: 1024
- refstack_defcore:
+ tempest_neutron:
flavor_ram: 1024
- patrole:
+ tempest_cinder:
flavor_ram: 1024
- vmtp:
- flavor_ram: 2048
- shaker:
+ tempest_keystone:
flavor_ram: 1024
- neutron_trunk:
+ tempest_heat:
flavor_ram: 1024
- networking-bgpvpn:
+ tempest_telemetry:
+ flavor_ram: 1024
+ rally_sanity:
flavor_ram: 1024
- networking-sfc:
+ refstack_compute:
flavor_ram: 1024
- barbican:
+ refstack_object:
+ flavor_ram: 1024
+ refstack_platform:
flavor_ram: 1024
tempest_full:
flavor_ram: 1024
tempest_scenario:
flavor_ram: 1024
- rally_sanity:
+ tempest_slow:
+ flavor_ram: 1024
+ patrole:
+ flavor_ram: 1024
+ tempest_barbican:
+ flavor_ram: 1024
+ tempest_octavia:
+ flavor_ram: 1024
+ tempest_neutron_cntt:
+ flavor_ram: 1024
+ tempest_cinder_cntt:
+ flavor_ram: 1024
+ tempest_keystone_cntt:
+ flavor_ram: 1024
+ tempest_heat_cntt:
+ flavor_ram: 1024
+ rally_sanity_cntt:
+ flavor_ram: 1024
+ tempest_full_cntt:
+ flavor_ram: 1024
+ tempest_scenario_cntt:
+ flavor_ram: 1024
+ tempest_slow_cntt:
flavor_ram: 1024
rally_full:
flavor_ram: 1024
+ rally_jobs:
+ flavor_ram: 1024
+ vmtp:
+ flavor_ram: 2048
+ shaker:
+ flavor_ram: 1024
+ rally_full_cntt:
+ flavor_ram: 1024
+ rally_jobs_cntt:
+ flavor_ram: 1024
ovs:
- general:
- openstack:
- flavor_ram: 1024
- snaps:
- flavor_extra_specs: {'hw:mem_page_size':'large'}
vmready1:
flavor_ram: 1024
vmready2:
@@ -70,123 +249,238 @@ ovs:
flavor_ram: 1024
tempest_smoke:
flavor_ram: 1024
- neutron-tempest-plugin-api:
+ tempest_horizon:
flavor_ram: 1024
- refstack_defcore:
+ tempest_neutron:
flavor_ram: 1024
- patrole:
+ tempest_cinder:
flavor_ram: 1024
- vmtp:
- flavor_ram: 2048
- shaker:
+ tempest_keystone:
+ flavor_ram: 1024
+ tempest_heat:
+ flavor_ram: 1024
+ tempest_telemetry:
flavor_ram: 1024
- neutron_trunk:
+ rally_sanity:
flavor_ram: 1024
- networking-bgpvpn:
+ refstack_compute:
flavor_ram: 1024
- networking-sfc:
+ refstack_object:
flavor_ram: 1024
- barbican:
+ refstack_platform:
flavor_ram: 1024
tempest_full:
flavor_ram: 1024
tempest_scenario:
flavor_ram: 1024
- rally_sanity:
+ tempest_slow:
+ flavor_ram: 1024
+ patrole:
+ flavor_ram: 1024
+ tempest_barbican:
+ flavor_ram: 1024
+ tempest_octavia:
+ flavor_ram: 1024
+ tempest_neutron_cntt:
+ flavor_ram: 1024
+ tempest_cinder_cntt:
+ flavor_ram: 1024
+ tempest_keystone_cntt:
+ flavor_ram: 1024
+ tempest_heat_cntt:
+ flavor_ram: 1024
+ rally_sanity_cntt:
+ flavor_ram: 1024
+ tempest_full_cntt:
+ flavor_ram: 1024
+ tempest_scenario_cntt:
+ flavor_ram: 1024
+ tempest_slow_cntt:
flavor_ram: 1024
rally_full:
flavor_ram: 1024
+ rally_jobs:
+ flavor_ram: 1024
+ vmtp:
+ flavor_ram: 2048
+ shaker:
+ flavor_ram: 1024
+ rally_full_cntt:
+ flavor_ram: 1024
+ rally_jobs_cntt:
+ flavor_ram: 1024
vio:
vmready1:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
vmready2:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
singlevm1:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
singlevm2:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
vping_ssh:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
vping_userdata:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
cinder_test:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
tempest_smoke:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_alt_format: vmdk
- neutron-tempest-plugin-api:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ tempest_horizon:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_alt_format: vmdk
- refstack_defcore:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ tempest_neutron:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_alt_format: vmdk
- patrole:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ tempest_cinder:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_alt_format: vmdk
- vmtp:
- image:
- /home/opnfv/functest/images/ubuntu-14.04-server-cloudimg-amd64-disk1.vmdk
+ tempest_keystone:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- shaker:
- image: /home/opnfv/functest/images/shaker-image.vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_alt_format: vmdk
+ tempest_heat:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- neutron_trunk:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image_alt:
+ /home/opnfv/functest/images/Fedora-Cloud-Base-30-1.2.x86_64.vmdk
+ image_alt_format: vmdk
+ tempest_telemetry:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_alt_format: vmdk
- networking-bgpvpn:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ rally_sanity:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ refstack_compute:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_alt_format: vmdk
- networking-sfc:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ refstack_object:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_alt_format: vmdk
- barbican:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ refstack_platform:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_alt_format: vmdk
tempest_full:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_alt_format: vmdk
tempest_scenario:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
- image_alt: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_alt_format: vmdk
- rally_sanity:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ tempest_slow:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_alt_format: vmdk
+ patrole:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_alt_format: vmdk
+ tempest_barbican:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_alt_format: vmdk
+ tempest_octavia:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_alt_format: vmdk
+ tempest_neutron_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_alt_format: vmdk
+ tempest_cinder_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_alt_format: vmdk
+ tempest_keystone_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_alt_format: vmdk
+ tempest_heat_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ image_alt:
+ /home/opnfv/functest/images/Fedora-Cloud-Base-30-1.2.x86_64.vmdk
+ image_alt_format: vmdk
+ rally_sanity_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ tempest_full_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_alt_format: vmdk
+ tempest_scenario_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_alt_format: vmdk
+ tempest_slow_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ image_alt: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_alt_format: vmdk
rally_full:
- image: /home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.vmdk
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ rally_jobs:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ vmtp:
+ image:
+ /home/opnfv/functest/images/ubuntu-14.04-server-cloudimg-amd64-disk1.vmdk
+ image_format: vmdk
+ shaker:
+ image: /home/opnfv/functest/images/shaker-image.vmdk
+ image_format: vmdk
+ rally_full_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
+ image_format: vmdk
+ rally_jobs_cntt:
+ image: /home/opnfv/functest/images/cirros-0.5.1-x86_64-disk.vmdk
image_format: vmdk
cloudify:
- image: /home/opnfv/functest/images/cloudify-manager-premium-4.0.1.vmdk
+ image:
+ /home/opnfv/functest/images/ubuntu-16.04-server-cloudimg-amd64-disk1.vmdk
image_format: vmdk
cloudify_ims:
- image: /home/opnfv/functest/images/cloudify-manager-premium-4.0.1.vmdk
+ image:
+ /home/opnfv/functest/images/ubuntu-16.04-server-cloudimg-amd64-disk1.vmdk
image_format: vmdk
image_alt:
/home/opnfv/functest/images/ubuntu-14.04-server-cloudimg-amd64-disk1.vmdk
@@ -196,7 +490,8 @@ vio:
/home/opnfv/functest/images/ubuntu-14.04-server-cloudimg-amd64-disk1.vmdk
image_format: vmdk
vyos_vrouter:
- image: /home/opnfv/functest/images/cloudify-manager-premium-4.0.1.vmdk
+ image:
+ /home/opnfv/functest/images/ubuntu-16.04-server-cloudimg-amd64-disk1.vmdk
image_format: vmdk
image_alt: /home/opnfv/functest/images/vyos-1.1.7.vmdk
image_alt_format: vmdk
diff --git a/functest/ci/convert_images.sh b/functest/ci/convert_images.sh
index d7ed3887b..2159d2a60 100644
--- a/functest/ci/convert_images.sh
+++ b/functest/ci/convert_images.sh
@@ -1,11 +1,13 @@
-#!/bin/bash
+#!/bin/sh
set -ex
-pushd "${1:-/home/opnfv/functest/images}"
+initdir=$(pwd)
+
+cd "${1:-/home/opnfv/functest/images}"
for i in *.img *.qcow2; do
qemu-img convert -f qcow2 -O vmdk "$i" "${i%.*}.vmdk"
done
-popd
+cd $initdir
diff --git a/functest/ci/download_images.sh b/functest/ci/download_images.sh
index b4abc532e..a56c02b60 100644
--- a/functest/ci/download_images.sh
+++ b/functest/ci/download_images.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
set -ex
@@ -6,18 +6,14 @@ wget_opts="-N --tries=1 --connect-timeout=30"
[ -t 1 ] || wget_opts="${wget_opts} --progress=dot:giga"
cat << EOF | wget ${wget_opts} -i - -P ${1:-/home/opnfv/functest/images}
-http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img
+http://download.cirros-cloud.net/0.6.1/cirros-0.6.1-x86_64-disk.img
https://cloud-images.ubuntu.com/releases/14.04/release/ubuntu-14.04-server-cloudimg-amd64-disk1.img
-https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2
https://cloud-images.ubuntu.com/releases/16.04/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img
-http://repository.cloudifysource.org/cloudify/4.0.1/sp-release/cloudify-manager-premium-4.0.1.qcow2
-http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-aarch64-disk.img
-https://cloud-images.ubuntu.com/releases/14.04/release/ubuntu-14.04-server-cloudimg-arm64-uefi1.img
-http://cloud.centos.org/altarch/7/images/aarch64/CentOS-7-aarch64-GenericCloud.qcow2.xz
-https://sourceforge.net/projects/ool-opnfv/files/vyos-1.1.7.img
-http://testresults.opnfv.org/functest/shaker-image.qcow2
-http://testresults.opnfv.org/functest/shaker-image-arm64.qcow2
+https://cloud-images.ubuntu.com/releases/18.04/release/ubuntu-18.04-server-cloudimg-amd64.img
+http://download.cirros-cloud.net/0.6.1/cirros-0.6.1-aarch64-disk.img
+http://repository.cloudifysource.org/cloudify/19.01.24/community-release/cloudify-docker-manager-community-19.01.24.tar
+http://testresults.opnfv.org/functest/vyos-1.1.8-amd64.qcow2
+http://testresults.opnfv.org/functest/shaker-image-1.3.4+stretch.qcow2
+https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/30/Cloud/x86_64/images/Fedora-Cloud-Base-30-1.2.x86_64.qcow2
+https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/30/Cloud/aarch64/images/Fedora-Cloud-Base-30-1.2.aarch64.qcow2
EOF
-
-xz --decompress --force --keep \
- ${1:-/home/opnfv/functest/images}/CentOS-7-aarch64-GenericCloud.qcow2.xz
diff --git a/functest/ci/logging.debug.ini b/functest/ci/logging.debug.ini
new file mode 100644
index 000000000..c926a5055
--- /dev/null
+++ b/functest/ci/logging.debug.ini
@@ -0,0 +1,110 @@
+[loggers]
+keys=root,functest,api,ci,core,cli,opnfv_tests,utils,xtesting,xci,xcore,xutils,sfc,baro,warnings
+
+[handlers]
+keys=console,wconsole,file,dfile
+
+[formatters]
+keys=standard
+
+[logger_root]
+level=NOTSET
+handlers=dfile
+
+[logger_functest]
+level=NOTSET
+handlers=file
+qualname=functest
+
+[logger_api]
+level=NOTSET
+handlers=wconsole
+qualname=functest.api
+
+[logger_ci]
+level=NOTSET
+handlers=console
+qualname=functest.ci
+
+[logger_core]
+level=NOTSET
+handlers=console
+qualname=functest.core
+
+[logger_cli]
+level=NOTSET
+handlers=wconsole
+qualname=functest.cli
+
+[logger_opnfv_tests]
+level=NOTSET
+handlers=wconsole
+qualname=functest.opnfv_tests
+
+[logger_utils]
+level=NOTSET
+handlers=wconsole
+qualname=functest.utils
+
+[logger_xtesting]
+level=NOTSET
+handlers=file
+qualname=xtesting
+
+[logger_xci]
+level=NOTSET
+handlers=console
+qualname=xtesting.ci
+
+[logger_xcore]
+level=NOTSET
+handlers=console
+qualname=xtesting.core
+
+[logger_xutils]
+level=NOTSET
+handlers=wconsole
+qualname=xtesting.utils
+
+[logger_sfc]
+level=NOTSET
+handlers=file,wconsole
+qualname=sfc
+
+[logger_baro]
+level=NOTSET
+handlers=file,wconsole
+qualname=baro_tests
+
+[logger_warnings]
+level=NOTSET
+handlers=file,console
+qualname=py.warnings
+
+[handler_console]
+class=StreamHandler
+level=INFO
+formatter=standard
+args=(sys.stdout,)
+
+[handler_wconsole]
+class=StreamHandler
+level=WARN
+formatter=standard
+args=(sys.stdout,)
+
+[handler_file]
+class=FileHandler
+level=INFO
+formatter=standard
+args=("/home/opnfv/functest/results/functest.log",)
+
+[handler_dfile]
+class=FileHandler
+level=DEBUG
+formatter=standard
+args=("/home/opnfv/functest/results/functest.debug.log",)
+
+[formatter_standard]
+format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
+datefmt=
diff --git a/functest/ci/logging.ini b/functest/ci/logging.ini
index f14014354..dde079493 100644
--- a/functest/ci/logging.ini
+++ b/functest/ci/logging.ini
@@ -1,15 +1,15 @@
[loggers]
-keys=root,functest,api,ci,core,cli,opnfv_tests,utils,xtesting,xci,xcore,energy,xutils,sfc,sdnvpn,baro,warnings
+keys=root,functest,api,ci,core,cli,opnfv_tests,utils,xtesting,xci,xcore,xutils,sfc,baro,warnings
[handlers]
-keys=console,wconsole,file,dfile
+keys=console,wconsole,file,null
[formatters]
keys=standard
[logger_root]
level=NOTSET
-handlers=dfile
+handlers=null
[logger_functest]
level=NOTSET
@@ -61,11 +61,6 @@ level=NOTSET
handlers=console
qualname=xtesting.core
-[logger_energy]
-level=NOTSET
-handlers=wconsole
-qualname=xtesting.energy
-
[logger_xutils]
level=NOTSET
handlers=wconsole
@@ -76,11 +71,6 @@ level=NOTSET
handlers=file,wconsole
qualname=sfc
-[logger_sdnvpn]
-level=NOTSET
-handlers=file,wconsole
-qualname=sdnvpn
-
[logger_baro]
level=NOTSET
handlers=file,wconsole
@@ -91,6 +81,12 @@ level=NOTSET
handlers=file,console
qualname=py.warnings
+[handler_null]
+class=NullHandler
+level=NOTSET
+formatter=standard
+args=()
+
[handler_console]
class=StreamHandler
level=INFO
@@ -105,16 +101,10 @@ args=(sys.stdout,)
[handler_file]
class=FileHandler
-level=DEBUG
+level=INFO
formatter=standard
args=("/home/opnfv/functest/results/functest.log",)
-[handler_dfile]
-class=FileHandler
-level=DEBUG
-formatter=standard
-args=("/home/opnfv/functest/results/functest.debug.log",)
-
[formatter_standard]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
diff --git a/functest/ci/rally_aarch64_patch.conf b/functest/ci/rally_aarch64_patch.conf
index baeceac76..4ea0d7605 100644
--- a/functest/ci/rally_aarch64_patch.conf
+++ b/functest/ci/rally_aarch64_patch.conf
@@ -1,5 +1,5 @@
img_name_regex = ^TestVM$
-img_url = http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-aarch64-disk.img
+img_url = http://download.cirros-cloud.net/0.5.1/cirros-0.5.1-aarch64-disk.img
flavor_ref_ram = 256
flavor_ref_alt_ram = 256
heat_instance_type_ram = 256
diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml
index 16365b0b7..acf5a7199 100644
--- a/functest/ci/testcases.yaml
+++ b/functest/ci/testcases.yaml
@@ -2,7 +2,6 @@
tiers:
-
name: healthcheck
- order: 0
description: >-
First tier to be executed to verify the basic
operations in the VIM.
@@ -28,6 +27,8 @@ tiers:
It creates and configures all tenant network ressources
required by advanced testcases (subnet, network and
router).
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: tenantnetwork1
@@ -40,6 +41,8 @@ tiers:
It creates new user/project before creating and configuring
all tenant network ressources required by a testcase
(subnet, network and router).
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: tenantnetwork2
@@ -146,70 +149,125 @@ tiers:
- /src/odl_test/csit/suites/openstack/neutron
-
- case_name: api_check
+ case_name: tempest_smoke
project_name: functest
criteria: 100
- blocking: true
+ blocking: false
description: >-
- This test case verifies the retrieval of OpenStack clients:
- Keystone, Glance, Neutron and Nova and may perform some
- simple queries. When the config value of
- snaps.use_keystone is True, functest must have access to
- the cloud's private network.
+ This test case runs the smoke subset of the OpenStack
+ Tempest suite. The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deplopyment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L114
run:
- name: api_check
+ name: tempest_common
+ args:
+ mode: '(?=.*\[.*\bsmoke\b.*\])(^tempest\.api)'
+ option:
+ - '--concurrency=4'
-
- case_name: snaps_health_check
+ case_name: tempest_horizon
project_name: functest
criteria: 100
- blocking: true
+ blocking: false
description: >-
- This test case creates executes the SimpleHealthCheck
- Python test class which creates an, image, flavor, network,
- and Cirros VM instance and observes the console output to
- validate the single port obtains the correct IP address.
+ This test case runs the Tempest suite proposed by the
+ Horizon project.
+ dependencies:
+ - DASHBOARD_URL: '^(?!\s*$).+'
run:
- name: snaps_health_check
+ name: tempest_common
+ args:
+ mode: '^tempest.scenario.test_dashboard_basic_ops.'
-
name: smoke
- order: 1
description: >-
Set of basic Functional tests to validate the OPNFV scenarios.
testcases:
-
- case_name: tempest_smoke
+ case_name: tempest_neutron
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case runs the smoke subset of the OpenStack
- Tempest suite. The list of test cases is generated by
+ This test case runs the Tempest suite proposed by the
+ Neutron project. The list of test cases is generated by
Tempest automatically and depends on the parameters of
- the OpenStack deplopyment.
- https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L114
+ the OpenStack deployment.
run:
name: tempest_common
args:
- mode: '(?=.*\[.*\bsmoke\b.*\])(^tempest\.api)'
+ mode: '^neutron_tempest_plugin\.api'
option:
- '--concurrency=4'
-
- case_name: neutron-tempest-plugin-api
+ case_name: tempest_cinder
project_name: functest
criteria: 100
blocking: false
description: >-
This test case runs the Tempest suite proposed by the
- Neutron project. The list of test cases is generated by
- Tempest automatically and depends on the parameters of
- the OpenStack deployment.
+ Cinder project.
run:
name: tempest_common
args:
- mode: '^neutron_tempest_plugin\.api'
+ mode: "(?!.*test_incremental_backup)\
+ (?!.*test_backup_crossproject_admin_negative)\
+ (?!.*test_backup_crossproject_user_negative)\
+ (^cinder_tempest_plugin.)"
+ option:
+ - '--concurrency=4'
+
+ -
+ case_name: tempest_keystone
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs the Tempest suite proposed by the
+ Keystone project.
+ run:
+ name: tempest_common
+ args:
+ mode: 'keystone_tempest_plugin.'
+ option:
+ - '--concurrency=4'
+
+ -
+ case_name: tempest_heat
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs the Tempest suite proposed by the
+ Heat project.
+ run:
+ name: tempest_heat
+ args:
+ mode: '^heat_tempest_plugin.tests'
+ option:
+ - '--concurrency=1'
+
+ -
+ case_name: tempest_telemetry
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs the Tempest suite proposed by the
+ Telemetry project.
+ run:
+ name: tempest_common
+ args:
+ mode: "(?!.*test_autoscaling)(?!.*test_live)\
+ (^telemetry_tempest_plugin)"
+ services:
+ - aodh
+ - gnocchi
+ - panko
option:
- '--concurrency=4'
@@ -223,123 +281,251 @@ tiers:
Rally suite in smoke mode.
run:
name: rally_sanity
+ args:
+ optional:
+ - 'gnocchi'
+ - 'barbican'
-
- case_name: rally_jobs
+ case_name: refstack_compute
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case runs a group of Rally jobs used in
- OpenStack gating
+ This test case runs a sub group of tests of the OpenStack
+ Compute testcases.
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
- name: rally_jobs
+ name: refstack
+ args:
+ target: compute
+ option:
+ - '--concurrency=4'
-
- case_name: refstack_defcore
+ case_name: refstack_object
project_name: functest
criteria: 100
blocking: false
description: >-
This test case runs a sub group of tests of the OpenStack
- Defcore testcases.
+ Object testcases.
run:
- name: refstack_defcore
+ name: refstack
args:
+ target: object
option:
- '--concurrency=4'
-
- case_name: patrole
+ case_name: refstack_platform
project_name: functest
criteria: 100
blocking: false
description: >-
- Test suite from Patrole project.
+ This test case runs a sub group of tests of the OpenStack
+ Platform testcases.
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
- name: patrole
+ name: refstack
args:
- role: 'admin'
- includes:
- - 'image'
- - 'network'
- excludes:
- - 'test_networks_multiprovider_rbac'
- - 'test_auto_allocated_topology_rbac'
+ target: platform
+ option:
+ - '--concurrency=4'
-
- case_name: snaps_smoke
+ case_name: tempest_full
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case contains tests that setup and destroy
- environments with VMs with and without Floating IPs
- with a newly created user and project. Set the config
- value snaps.use_floating_ips (True|False) to toggle
- this functionality. When the config value of
- snaps.use_keystone is True, functest must have access to
- the cloud's private network.
+ The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L83
run:
- name: snaps_smoke
+ name: tempest_common
+ args:
+ mode: '(?!.*\[.*\bslow\b.*\])(^tempest\.api)'
+ option:
+ - '--concurrency=4'
-
- case_name: neutron_trunk
+ case_name: tempest_scenario
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case runs the neutron trunk subtest of the
- OpenStack Tempest suite. The list of test cases is
- generated by Tempest having as input the relevant
- testcase list file.
+ The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L84
run:
name: tempest_common
args:
- mode: 'neutron_tempest_plugin.(api|scenario).test_trunk'
- neutron_extensions:
- - trunk
- - trunk-details
+ mode: '(?!.*\[.*\bslow\b.*\])(^tempest\.scenario)'
+ option:
+ - '--concurrency=1'
-
- case_name: networking-bgpvpn
+ case_name: tempest_slow
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case runs OpenStack networking-bgpvpn Tempest
- suite. The list of test cases is generated by Tempest
- having as input the relevant regex.
+ The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L84
run:
name: tempest_common
args:
- mode: '^networking_bgpvpn_tempest\.'
- neutron_extensions:
- - bgpvpn
+ mode: '(?=.*\[.*\bslow\b.*\])(^tempest\.)'
+ option:
+ - '--concurrency=1'
+
+ -
+ case_name: patrole_admin
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ Test suite from Patrole project.
+ run:
+ name: patrole
+ args:
+ roles: 'admin'
+ mode: "(?!.*test_unmanage_snapshot_rbac)\
+ (?!.*test_show_auto_allocated_topology)\
+ (?!.*test_delete_auto_allocated_topology)\
+ (?!.*test_create_network_provider_segmentation_id)\
+ (?!.*compute.test_floating_ips_rbac)\
+ (?!.*test_reset_network)\
+ (?!.*test_create_image_from_volume_backed_server)\
+ (?!.*test_network_ip_availability_rbac.NetworkIpAvailabilityExtRbacTest.test_get_network_ip_availabilities)\
+ (?!.*test_policy_bandwidth_limit_rule_rbac)\
+ (?!.*test_policy_minimum_bandwidth_rule_rbac)\
+ (?!.*test_group_type_specs)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_create_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_delete_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_update_group_type)\
+ (?!.*test_group_snapshots_rbac)\
+ (?!.*test_groups_rbac)\
+ (?!.*test_quota_classes_rbac)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_create_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_delete_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_show_interface)\
+ (?!.*test_user_messages_rbac)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV310RbacTest)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV312RbacTest)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_delete_volume_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_list_volumes_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_show_volume_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_update_volume_image_metadata)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV318RbacTest)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV39RbacTest)\
+ (?!.*test_volume_types_rbac)\
+ (?=.*[.*\bslow\b.*])\
+ (^patrole_tempest_plugin.tests.api.(compute|image|network|volume))"
option:
- '--concurrency=4'
-
- case_name: networking-sfc
+ case_name: patrole_member
project_name: functest
criteria: 100
blocking: false
description: >-
- This test case runs OpenStack networking-sfc Tempest
- suite. The list of test cases is generated by Tempest
- having as input the relevant regex.
+ Test suite from Patrole project.
run:
- name: tempest_common
+ name: patrole
args:
- mode:
- '^(?:networking_sfc\.tests\.tempest_plugin.tests.api).*$'
- neutron_extensions:
- - sfc
+ roles: 'member'
+ mode: "(?!.*test_unmanage_snapshot_rbac)\
+ (?!.*test_show_auto_allocated_topology)\
+ (?!.*test_delete_auto_allocated_topology)\
+ (?!.*test_create_network_provider_segmentation_id)\
+ (?!.*compute.test_floating_ips_rbac)\
+ (?!.*test_reset_network)\
+ (?!.*test_create_image_from_volume_backed_server)\
+ (?!.*test_network_ip_availability_rbac.NetworkIpAvailabilityExtRbacTest.test_get_network_ip_availabilities)\
+ (?!.*test_policy_bandwidth_limit_rule_rbac)\
+ (?!.*test_policy_minimum_bandwidth_rule_rbac)\
+ (?!.*test_group_type_specs)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_create_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_delete_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_update_group_type)\
+ (?!.*test_group_snapshots_rbac)\
+ (?!.*test_groups_rbac)\
+ (?!.*test_quota_classes_rbac)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_create_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_delete_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_show_interface)\
+ (?!.*test_user_messages_rbac)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV310RbacTest)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV312RbacTest)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_delete_volume_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_list_volumes_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_show_volume_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_update_volume_image_metadata)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV318RbacTest)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV39RbacTest)\
+ (?!.*test_volume_types_rbac)\
+ (?=.*[.*\bslow\b.*])\
+ (^patrole_tempest_plugin.tests.api.(compute|image|network|volume))"
option:
- - '--concurrency=0'
+ - '--concurrency=4'
-
- case_name: barbican
+ case_name: patrole_reader
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ Test suite from Patrole project.
+ run:
+ name: patrole
+ args:
+ roles: 'reader'
+ mode: "(?!.*test_unmanage_snapshot_rbac)\
+ (?!.*test_show_auto_allocated_topology)\
+ (?!.*test_delete_auto_allocated_topology)\
+ (?!.*test_create_network_provider_segmentation_id)\
+ (?!.*compute.test_floating_ips_rbac)\
+ (?!.*test_reset_network)\
+ (?!.*test_create_image_from_volume_backed_server)\
+ (?!.*test_network_ip_availability_rbac.NetworkIpAvailabilityExtRbacTest.test_get_network_ip_availabilities)\
+ (?!.*test_policy_bandwidth_limit_rule_rbac)\
+ (?!.*test_policy_minimum_bandwidth_rule_rbac)\
+ (?!.*test_group_type_specs)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_create_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_delete_group_type)\
+ (?!.*test_groups_rbac.GroupTypesV3RbacTest.test_update_group_type)\
+ (?!.*test_group_snapshots_rbac)\
+ (?!.*test_groups_rbac)\
+ (?!.*test_quota_classes_rbac)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_create_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_delete_interface)\
+ (?!.*test_server_misc_policy_actions_rbac.MiscPolicyActionsNetworkRbacTest.test_show_interface)\
+ (?!.*test_user_messages_rbac)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV310RbacTest)\
+ (?!.*test_volume_actions_rbac.VolumesActionsV312RbacTest)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_delete_volume_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_list_volumes_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_show_volume_details_image_metadata)\
+ (?!.*test_volume_metadata_rbac.VolumeMetadataV3RbacTest.test_update_volume_image_metadata)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV318RbacTest)\
+ (?!.*test_volumes_backup_rbac.VolumesBackupsV39RbacTest)\
+ (?!.*test_volume_types_rbac)\
+ (?=.*[.*\bslow\b.*])\
+ (^patrole_tempest_plugin.tests.api.(compute|image|network|volume))"
+ option:
+ - '--concurrency=4'
+
+ -
+ case_name: tempest_barbican
project_name: functest
criteria: 100
blocking: false
@@ -353,177 +539,343 @@ tiers:
'^barbican_tempest_plugin.((?!test_signed_image_upload_boot_failure).)*$'
services:
- barbican
+ option:
+ - '--concurrency=4'
- -
- name: benchmarking
- order: 2
- description: >-
- Run several OpenStack performance tools
- https://docs.openstack.org/performance-docs/latest/methodologies/tools.html
- testcases:
-
- case_name: vmtp
+ case_name: tempest_octavia
project_name: functest
criteria: 100
blocking: false
description: >-
- VMTP is a small python application that will automatically
- perform ping connectivity, round trip time measurement
- (latency) and TCP/UDP throughput
- dependencies:
- - POD_ARCH: '^(?!aarch64$)'
+ It leverages on the tempest plugin containing tests used to
+ verify the functionality of an octavia installation.
run:
- name: vmtp
+ name: tempest_common
+ args:
+ mode: "(?!.*api.v2.test_availability_zone)\
+ (?!.*api.v2.test_availability_zone_profile)\
+ (?!.*api.v2.test_member.MemberAPITest.test_member_ipv4_create)\
+ (?!.*api.v2.test_member.MemberAPITest.test_member_ipv6_create)\
+ (^octavia_tempest_plugin.tests.(api|scenario))"
+ services:
+ - octavia
+ option:
+ - '--concurrency=2'
-
- case_name: shaker
+ case_name: tempest_cyborg
project_name: functest
criteria: 100
blocking: false
description: >-
- Shaker wraps around popular system network testing tools
- like iperf, iperf3 and netperf (with help of flent). Shaker
- is able to deploy OpenStack instances and networks in
- different topologies.
+ It leverages on the tempest plugin containing tests used to
+ verify the functionality of a cyborg installation.
run:
- name: shaker
+ name: tempest_common
+ args:
+ mode: '^cyborg_tempest_plugin'
+ services:
+ - cyborg
+ option:
+ - '--concurrency=4'
-
- name: features
- order: 3
+ name: smoke_cntt
description: >-
- Test suites from feature projects
- integrated in functest
+ Set of basic Functional tests to validate the OPNFV scenarios.
testcases:
-
- case_name: doctor-notification
- project_name: doctor
- enabled: false
+ case_name: tempest_neutron_cntt
+ project_name: functest
criteria: 100
blocking: false
+ deny_skipping: true
+ tests_count: 564
description: >-
- Test suite from Doctor project.
- dependencies:
- - INSTALLER_TYPE: '(apex)|(fuel)|(daisy)'
- - DEPLOY_SCENARIO: '^((?!fdio|nofeature).)*$'
+ This test case runs the Tempest suite proposed by the
+ Neutron project. The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
run:
- name: bashfeature
+ name: tempest_common
args:
- cmd: 'doctor-test'
-
- -
- case_name: bgpvpn
- project_name: sdnvpn
- enabled: false
- criteria: 100
- blocking: false
- description: >-
- Test suite from SDNVPN project.
- dependencies:
- - DEPLOY_SCENARIO: 'bgpvpn'
- run:
- name: bgpvpn
+ mode: "(?!.*admin.test_agent_availability_zone)\
+ (?!.*admin.test_dhcp_agent_scheduler)\
+ (?!.*admin.test_l3_agent_scheduler)\
+ (?!.*admin.test_logging)\
+ (?!.*admin.test_logging_negative)\
+ (?!.*admin.test_network_segment_range)\
+ (?!.*admin.test_ports.PortTestCasesAdmin.test_regenerate_mac_address)\
+ (?!.*admin.test_ports.PortTestCasesResourceRequest)\
+ (?!.*admin.test_routers_dvr)\
+ (?!.*admin.test_routers_flavors)\
+ (?!.*admin.test_routers_ha)\
+ (?!.*test_conntrack_helper)\
+ (?!.*test_floating_ips.FloatingIPPoolTestJSON)\
+ (?!.*test_floating_ips.FloatingIPTestJSON.test_create_update_floatingip_port_details)\
+ (?!.*test_local_ip)\
+ (?!.*test_metering_extensions)\
+ (?!.*test_metering_negative)\
+ (?!.*test_networks.NetworksSearchCriteriaTest.test_list_validation_filters)\
+ (?!.*test_networks.NetworksTestAdmin.test_create_tenant_network_vxlan)\
+ (?!.*test_networks.NetworksTestJSON.test_create_update_network_dns_domain)\
+ (?!.*test_port_forwardings)\
+ (?!.*test_ports.PortsTaggingOnCreation)\
+ (?!.*test_ports.PortsTestJSON.test_create_port_with_propagate_uplink_status)\
+ (?!.*test_ports.PortsTestJSON.test_create_port_without_propagate_uplink_status)\
+ (?!.*test_ports.PortsTestJSON.test_create_update_port_with_dns_domain)\
+ (?!.*test_ports.PortsTestJSON.test_create_update_port_with_dns_name)\
+ (?!.*test_ports.PortsTestJSON.test_create_update_port_with_no_dns_name)\
+ (?!.*test_qos.QosMinimumBandwidthRuleTestJSON)\
+ (?!.*test_revisions.TestRevisions.test_update_dns_domain_bumps_revision)\
+ (?!.*test_revisions.TestRevisions.test_update_router_extra_attributes_bumps_revision)\
+ (?!.*test_router_interface_fip)\
+ (?!.*test_routers.DvrRoutersTest)\
+ (?!.*test_routers.HaRoutersTest)\
+ (?!.*test_routers.RoutersIpV6Test.test_extra_routes_atomic)\
+ (?!.*test_routers.RoutersTest.test_extra_routes_atomic)\
+ (?!.*test_routers_negative.DvrRoutersNegativeTest)\
+ (?!.*test_routers_negative.DvrRoutersNegativeTestExtended)\
+ (?!.*test_routers_negative.HaRoutersNegativeTest)\
+ (?!.*test_security_groups.RbacSharedSecurityGroupTest)\
+ (?!.*test_subnetpool_prefix_ops)\
+ (?!.*test_subnetpools.RbacSubnetPoolTest)\
+ (?!.*test_subnetpools.SubnetPoolsSearchCriteriaTest.test_list_validation_filters)\
+ (?!.*test_subnetpools_negative.SubnetPoolsNegativeTestJSON.test_tenant_create_subnetpool_associate_shared_address_scope)\
+ (?!.*test_subnets.SubnetsSearchCriteriaTest.test_list_validation_filters)\
+ (?!.*test_timestamp.TestTimeStamp.test_segment_with_timestamp)\
+ (?!.*test_trunk.TrunkTestInheritJSONBase.test_add_subport)\
+ (?!.*test_trunk.TrunkTestMtusJSON)\
+ (?!.*test_trunk_negative.TrunkTestJSON.test_create_subport_invalid_inherit_network_segmentation_type)\
+ (?!.*test_trunk_negative.TrunkTestMtusJSON)\
+ (^neutron_tempest_plugin.api)"
+ option:
+ - '--concurrency=4'
-
- case_name: functest-odl-sfc
- project_name: sfc
- enabled: false
+ case_name: tempest_cinder_cntt
+ project_name: functest
criteria: 100
blocking: false
+ deny_skipping: true
+ tests_count: 10
description: >-
- Test suite for odl-sfc to test two chains with one SF and
- one chain with two SFs
- dependencies:
- - DEPLOY_SCENARIO: 'odl.*sfc'
+ This test case runs the Tempest suite proposed by the
+ Cinder project.
run:
- name: functest-odl-sfc
+ name: tempest_common
+ args:
+ mode: "(?!.*test_incremental_backup)\
+ (?!.*test_consistencygroups)\
+ (?!.*test_backup_crossproject_admin_negative)\
+ (?!.*test_backup_crossproject_user_negative)\
+ (?!.*test_volume_encrypted.TestEncryptedCinderVolumes)\
+ (?!.*rbac)\
+ (^cinder_tempest_plugin.)"
+ option:
+ - '--concurrency=4'
-
- case_name: barometercollectd
- project_name: barometer
- enabled: false
+ case_name: tempest_keystone_cntt
+ project_name: functest
criteria: 100
blocking: false
+ deny_skipping: true
+ tests_count: 27
description: >-
- Test suite for the Barometer project. Separate tests verify
- the proper configuration and basic functionality of all the
- collectd plugins as described in the Project Release Plan
- dependencies:
- - DEPLOY_SCENARIO: 'bar'
+ This test case runs the Tempest suite proposed by the
+ Keystone project.
run:
- name: barometercollectd
+ name: tempest_common
+ args:
+ mode: "(?!.*api.identity.v3.test_oauth1_tokens)\
+ (?!.*rbac)\
+ (?!.*scenario.test_federated_authentication)\
+ keystone_tempest_plugin."
+ option:
+ - '--concurrency=4'
-
- case_name: fds
- project_name: fastdatastacks
- enabled: false
+ case_name: tempest_heat_cntt
+ project_name: functest
criteria: 100
blocking: false
+ deny_skipping: true
+ tests_count: 124
description: >-
- Test Suite for the OpenDaylight SDN Controller when GBP
- features are installed. It integrates some test suites from
- upstream using Robot as the test framework.
- dependencies:
- - DEPLOY_SCENARIO: 'odl.*-fdio'
+ This test case runs the Tempest suite proposed by the
+ Heat project.
run:
- name: odl
+ name: tempest_heat
args:
- suites:
- - /src/fds/testing/robot
+ mode: "(?!.*functional.test_lbaasv2)\
+ (?!.*functional.test_encryption_vol_type)\
+ (?!.*functional.test_event_sinks)\
+ (?!.*functional.test_software_config.ZaqarSignalTransportTest)\
+ (?!.*functional.test_stack_events)\
+ (?!.*functional.test_waitcondition)\
+ (?!.*RemoteStackTest.test_stack_create_with_cloud_credential)\
+ (?!.*scenario.test_aodh_alarm)\
+ (?!.*tests.scenario.test_autoscaling_lb)\
+ (?!.*scenario.test_autoscaling_lbv2)\
+ (?!.*scenario.test_server_software_config)\
+ (?!.*test_volumes.VolumeBackupRestoreIntegrationTest)\
+ (?!.*scenario.test_octavia_lbaas)\
+ (?!.*scenario.test_server_cfn_init)\
+ ^heat_tempest_plugin.tests"
+ option:
+ - '--concurrency=1'
+
-
- case_name: vgpu
+ case_name: rally_sanity_cntt
project_name: functest
criteria: 100
blocking: false
description: >-
- Test suite for the OpenStack vGPU feature
- dependencies:
- - DEPLOY_SCENARIO: 'vgpu'
+ This test case runs a sub group of tests of the OpenStack
+ Rally suite in smoke mode.
run:
- name: vgpu
+ name: rally_sanity
+ args:
+ tests:
+ - 'authenticate'
+ - 'glance'
+ - 'cinder'
+ - 'heat'
+ - 'keystone'
+ - 'neutron'
+ - 'nova'
+ - 'quotas'
+ - 'swift'
-
- case_name: stor4nfv_os
- project_name: stor4nfv
- enabled: false
+ case_name: tempest_full_cntt
+ project_name: functest
criteria: 100
blocking: false
+ deny_skipping: true
+ tests_count: 1271
description: >-
- This tests are necessary demonstrate conformance
- of the OpenStack+Stor4NFV deployment.
- dependencies:
- - DEPLOY_SCENARIO: 'stor4nfv'
+ The list of test cases is generated by
+ Tempest automatically and depends on the parameters of
+ the OpenStack deployment.
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L83
run:
- name: stor4nfv_os
+ name: tempest_common
+ args:
+ mode: "(?!.*admin.test_agents)(?!.*test_fixed_ips)\
+ (?!.*test_fixed_ips_negative)\
+ (?!.*test_auto_allocate_network)(?!.*test_floating_ips_bulk)\
+ (?!.*test_flavors_microversions.FlavorsV255TestJSON)\
+ (?!.*test_flavors_microversions.FlavorsV261TestJSON)\
+ (?!.*test_live_migration.LiveAutoBlockMigrationV225Test.test_iscsi_volume)\
+ (?!.*test_live_migration.LiveAutoBlockMigrationV225Test.test_live_block_migration)\
+ (?!.*test_live_migration.LiveAutoBlockMigrationV225Test.test_live_block_migration_paused)\
+ (?!.*test_live_migration.LiveAutoBlockMigrationV225Test.test_volume_backed_live_migration)\
+ (?!.*test_live_migration.LiveMigrationTest.test_iscsi_volume)\
+ (?!.*test_live_migration.LiveMigrationTest.test_live_block_migration)\
+ (?!.*test_live_migration.LiveMigrationTest.test_live_block_migration_paused)\
+ (?!.*test_live_migration.LiveMigrationTest.test_volume_backed_live_migration)\
+ (?!.*test_live_migration.LiveMigrationRemoteConsolesV26Test)\
+ (?!.*test_quotas.QuotasAdminTestV257)\
+ (?!.*test_servers.ServersAdminTestJSON.test_reset_network_inject_network_info)\
+ (?!.*certificates.test_certificates)\
+ (?!.*test_quotas_negative.QuotasSecurityGroupAdminNegativeTest)\
+ (?!.*test_novnc)(?!.*test_server_personality)\
+ (?!.*test_servers.ServerShowV263Test.test_show_update_rebuild_list_server)\
+ (?!.*test_servers_microversions.ServerShowV254Test)\
+ (?!.*test_servers_microversions.ServerShowV257Test)\
+ (?!.*test_servers_negative.ServersNegativeTestJSON.test_personality_file_contents_not_encoded)\
+ (?!.*servers.test_virtual_interfaces)\
+ (?!.*test_server_actions.ServerActionsTestJSON.test_change_server_password)\
+ (?!.*test_server_actions.ServerActionsTestJSON.test_get_vnc_console)\
+ (?!.*test_server_actions.ServerActionsTestJSON.test_reboot_server_soft)\
+ (?!.*test_server_rescue.ServerBootFromVolumeStableRescueTest)\
+ (?!.*test_server_rescue.ServerStableDeviceRescueTest)\
+ (?!.*test_security_group_default_rules)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_security_group_create_with_duplicate_name)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_security_group_create_with_invalid_group_description)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_security_group_create_with_invalid_group_name)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_update_security_group_with_invalid_sg_des)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_update_security_group_with_invalid_sg_id)\
+ (?!.*test_security_groups_negative.SecurityGroupsNegativeTestJSON.test_update_security_group_with_invalid_sg_name)\
+ (?!.*test_create_server.ServersTestFqdnHostnames.test_create_server_with_fqdn_name)\
+ (?!.*test_server_metadata.ServerMetadataTestJSON)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_delete_metadata_non_existent_server)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_metadata_items_limit)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_set_metadata_invalid_key)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_set_metadata_non_existent_server)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_set_server_metadata_blank_key)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_set_server_metadata_missing_metadata)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_update_metadata_non_existent_server)\
+ (?!.*test_server_metadata_negative.ServerMetadataNegativeTestJSON.test_update_metadata_with_blank_key)\
+ (?!.*test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filtered_by_ip_regex)\
+ (?!.*compute.test_virtual_interfaces)(?!.*compute.test_virtual_interfaces_negative)\
+ (?!.*compute.test_networks)\
+ (?!.*test_attach_volume.AttachVolumeMultiAttach)\
+ (?!.*identity.admin.v2)(?!.*identity.v2)\
+ (?!.*identity.v3.test_access_rules)\
+ (?!.*identity.v3.test_application_credentials.ApplicationCredentialsV3Test.test_create_application_credential_access_rules)\
+ (?!.*image.v1)\
+ (?!.*image.v2.admin.test_images.ImportCopyImagesTest)\
+ (?!.*image.v2.test_images_negative.ImagesNegativeTest.test_create_image_reserved_property)\
+ (?!.*image.v2.test_images_negative.ImagesNegativeTest.test_update_image_reserved_property)\
+ (?!.*image.v2.test_images_negative.ImportImagesNegativeTest.test_image_web_download_import_with_bad_url)\
+ (?!.*image.v2.test_images.ImportImagesTest)\
+ (?!.*image.v2.test_images.MultiStoresImportImages)\
+ (?!.*admin.test_dhcp_agent_scheduler)\
+ (?!.*admin.test_routers_dvr)\
+ (?!.*test_metering_extensions)(?!.*network.test_tags)\
+ (?!.*test_routers_negative.DvrRoutersNegativeTest)\
+ (?!.*test_routers.RoutersIpV6Test.test_create_router_set_gateway_with_fixed_ip)\
+ (?!.*test_routers.RoutersTest.test_create_router_set_gateway_with_fixed_ip)\
+ (?!.*test_object_services.ObjectTest.test_create_object_with_transfer_encoding)\
+ (?!.*test_encrypted_volumes_extend)\
+ (?!.*test_group_snapshots.GroupSnapshotsV319Test.test_reset_group_snapshot_status)\
+ (?!.*test_multi_backend)\
+ (?!.*test_volume_retype.VolumeRetypeWithMigrationTest)\
+ (?!.*test_volume_delete_cascade.VolumesDeleteCascade.test_volume_from_snapshot_cascade_delete)\
+ (?!.*test_volumes_backup.VolumesBackupsTest.test_volume_backup_create_get_detailed_list_restore_delete)\
+ (?!.*test_volumes_negative.UpdateMultiattachVolumeNegativeTest.test_multiattach_rw_volume_update_failure)\
+ (?!.*test_volumes_extend.VolumesExtendAttachedTest.test_extend_attached_volume)\
+ (?!.*\\[.*\\bslow\\b.*\\])(^tempest.api)"
+ option:
+ - '--concurrency=4'
- -
- name: components
- order: 4
- description: >-
- Extensive testing of OpenStack API.
- testcases:
-
- case_name: tempest_full
+ case_name: tempest_scenario_cntt
project_name: functest
criteria: 100
blocking: false
+ deny_skipping: true
+ tests_count: 13
description: >-
The list of test cases is generated by
Tempest automatically and depends on the parameters of
the OpenStack deployment.
- https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L83
+ https://github.com/openstack/tempest/blob/18.0.0/tox.ini#L84
run:
- name: tempest_common
+ name: tempest_scenario
args:
- mode: '(?!.*\[.*\bslow\b.*\])(^tempest\.api)'
+ mode: "\
+ (?!.*test_compute_unified_limits)\
+ (?!.*test_minbw_allocation_placement)\
+ (?!.*test_network_qos_placement)\
+ (?!.*test_unified_limits.ImageQuotaTest.test_image_count_uploading_quota)\
+ (?!.*test_unified_limits.ImageQuotaTest.test_image_stage_quota)\
+ (?!.*test_volume_boot_pattern.TestVolumeBootPattern.test_boot_server_from_encrypted_volume_luks)\
+ (?!.*\\[.*\\bslow\\b.*\\])(^tempest.scenario)"
option:
- - '--concurrency=4'
+ - '--concurrency=1'
-
- case_name: tempest_scenario
+ case_name: tempest_slow_cntt
project_name: functest
criteria: 100
blocking: false
+ deny_skipping: true
+ tests_count: 43
description: >-
The list of test cases is generated by
Tempest automatically and depends on the parameters of
@@ -532,10 +884,27 @@ tiers:
run:
name: tempest_common
args:
- mode: '(?!.*\[.*\bslow\b.*\])(^tempest\.scenario)'
+ mode: "(?!.*test_volume_swap)\
+ (?!.*test_server_personality)\
+ (?!.*test_server_rescue.ServerBootFromVolumeStableRescueTest)\
+ (?!.*test_container_sync.ContainerSyncTest.test_container_synchronization)\
+ (?!.*test_container_sync_middleware.ContainerSyncMiddlewareTest.test_container_synchronization)\
+ (?!.*test_encrypted_cinder_volumes)\
+ (?!.*test_minbw_allocation_placement)\
+ (?!.*test_network_basic_ops.TestNetworkBasicOps.test_router_rescheduling)\
+ (?!.*test_shelve_instance.TestShelveInstance.test_cold_migrate_unshelved_instance)\
+ (?!.*test_volume_migrate_attached)\
+ (?!.*test_network_advanced_server_ops.TestNetworkAdvancedServerOps.test_server_connectivity_cold_migration_revert)\
+ (?=.*\\[.*\\bslow\\b.*\\])(^tempest.)"
option:
- '--concurrency=1'
+ -
+ name: benchmarking
+ description: >-
+ Run several OpenStack performance tools
+ https://docs.openstack.org/performance-docs/latest/methodologies/tools.html
+ testcases:
-
case_name: rally_full
project_name: functest
@@ -546,10 +915,100 @@ tiers:
OpenStack Rally suite using several threads and iterations.
run:
name: rally_full
+ args:
+ optional:
+ - 'gnocchi'
+ - 'barbican'
+
+ -
+ case_name: rally_jobs
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs a group of Rally jobs used in
+ OpenStack gating
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
+ run:
+ name: rally_jobs
+ args:
+ optional:
+ - 'gnocchi'
+
+ -
+ case_name: vmtp
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ VMTP is a small python application that will automatically
+ perform ping connectivity, round trip time measurement
+ (latency) and TCP/UDP throughput
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
+ run:
+ name: vmtp
+
+ -
+ case_name: shaker
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ Shaker wraps around popular system network testing tools
+ like iperf, iperf3 and netperf (with help of flent). Shaker
+ is able to deploy OpenStack instances and networks in
+ different topologies.
+ dependencies:
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
+ run:
+ name: shaker
+
+ -
+ name: benchmarking_cntt
+ description: >-
+ Run several OpenStack performance tools
+ https://docs.openstack.org/performance-docs/latest/methodologies/tools.html
+ testcases:
+ -
+ case_name: rally_full_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs the full suite of scenarios of the
+ OpenStack Rally suite using several threads and iterations.
+ run:
+ name: rally_full
+ args:
+ tests:
+ - 'authenticate'
+ - 'glance'
+ - 'cinder'
+ - 'heat'
+ - 'keystone'
+ - 'neutron'
+ - 'nova'
+ - 'quotas'
+ - 'swift'
+
+ -
+ case_name: rally_jobs_cntt
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case runs a group of Rally jobs used in
+ OpenStack gating
+ run:
+ name: rally_jobs
+ args:
+ tests:
+ - 'neutron'
-
name: vnf
- order: 5
description: >-
Collection of VNF test cases.
testcases:
@@ -560,8 +1019,6 @@ tiers:
blocking: false
description: >-
This test case deploys the Cloudify orchestrator.
- dependencies:
- - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
run:
name: cloudify
-
@@ -574,7 +1031,7 @@ tiers:
Clearwater using the Cloudify orchestrator. It also runs
some signaling traffic.
dependencies:
- - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: cloudify_ims
@@ -588,7 +1045,7 @@ tiers:
Clearwater using the OpenStack Heat orchestrator.
It also runs some signaling traffic.
dependencies:
- - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: heat_ims
@@ -600,7 +1057,7 @@ tiers:
description: >-
This test case is vRouter testing.
dependencies:
- - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: vyos_vrouter
@@ -613,6 +1070,6 @@ tiers:
vEPC validation with Juju as VNF manager and ABoT as test
executor.
dependencies:
- - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
+ - NO_TENANT_NETWORK: '^(?![tT]rue$)'
run:
name: juju_epc
diff --git a/functest/core/cloudify.py b/functest/core/cloudify.py
index a760b9fa2..966d33645 100644
--- a/functest/core/cloudify.py
+++ b/functest/core/cloudify.py
@@ -12,9 +12,13 @@
from __future__ import division
import logging
+import os
import time
+import traceback
from cloudify_rest_client import CloudifyClient
+from cloudify_rest_client.executions import Execution
+import scp
from functest.core import singlevm
@@ -25,24 +29,28 @@ class Cloudify(singlevm.SingleVm2):
__logger = logging.getLogger(__name__)
filename = ('/home/opnfv/functest/images/'
- 'cloudify-manager-premium-4.0.1.qcow2')
+ 'ubuntu-18.04-server-cloudimg-amd64.img')
flavor_ram = 4096
flavor_vcpus = 2
flavor_disk = 40
- username = 'centos'
+ username = 'ubuntu'
ssh_connect_loops = 12
create_server_timeout = 600
ports = [80, 443, 5671, 53333]
+ cloudify_archive = ('/home/opnfv/functest/images/'
+ 'cloudify-docker-manager-community-19.01.24.tar')
+ cloudify_container = "docker-cfy-manager:latest"
+
def __init__(self, **kwargs):
"""Initialize Cloudify testcase object."""
if "case_name" not in kwargs:
kwargs["case_name"] = "cloudify"
- super(Cloudify, self).__init__(**kwargs)
+ super().__init__(**kwargs)
self.cfy_client = None
def prepare(self):
- super(Cloudify, self).prepare()
+ super().prepare()
for port in self.ports:
self.cloud.create_security_group_rule(
self.sec.id, port_range_min=port, port_range_max=port,
@@ -52,12 +60,28 @@ class Cloudify(singlevm.SingleVm2):
"""
Deploy Cloudify Manager.
"""
+ scpc = scp.SCPClient(self.ssh.get_transport())
+ scpc.put(self.cloudify_archive,
+ remote_path=os.path.basename(self.cloudify_archive))
+ (_, stdout, stderr) = self.ssh.exec_command(
+ "sudo apt-get update && "
+ "sudo apt-get install -y docker.io && "
+ "sudo docker load -i "
+ f"~/{os.path.basename(self.cloudify_archive)} && "
+ "sudo docker run --name cfy_manager_local -d "
+ "--restart unless-stopped -v /sys/fs/cgroup:/sys/fs/cgroup:ro "
+ "--tmpfs /run --tmpfs /run/lock --security-opt seccomp:unconfined "
+ f"--cap-add SYS_ADMIN --network=host {self.cloudify_container}")
+ self.__logger.debug("output:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("error:\n%s", stderr.read().decode("utf-8"))
self.cfy_client = CloudifyClient(
- host=self.fip.floating_ip_address,
- username='admin', password='admin', tenant='default_tenant',
- api_version='v3')
+ host=self.fip.floating_ip_address if self.fip else (
+ self.sshvm.public_v4),
+ username='admin', password='admin', tenant='default_tenant')
self.__logger.info("Attemps running status of the Manager")
- for loop in range(10):
+ secret_key = "foo"
+ secret_value = "bar"
+ for loop in range(20):
try:
self.__logger.debug(
"status %s", self.cfy_client.manager.get_status())
@@ -66,18 +90,130 @@ class Cloudify(singlevm.SingleVm2):
"The current manager status is %s", cfy_status)
if str(cfy_status) != 'running':
raise Exception("Cloudify Manager isn't up and running")
- self.cfy_client.secrets.create("foo", "bar")
- self.__logger.debug(
- "List secrets: %s", self.cfy_client.secrets.list())
- self.cfy_client.secrets.delete("foo")
+ for secret in iter(self.cfy_client.secrets.list()):
+ if secret_key == secret["key"]:
+ self.__logger.debug("Updating secrets: %s", secret_key)
+ self.cfy_client.secrets.update(
+ secret_key, secret_value)
+ break
+ else:
+ self.__logger.debug("Creating secrets: %s", secret_key)
+ self.cfy_client.secrets.create(secret_key, secret_value)
+ self.cfy_client.secrets.delete(secret_key)
self.__logger.info("Secrets API successfully reached")
break
except Exception: # pylint: disable=broad-except
- self.__logger.info(
- "try %s: Cloudify Manager isn't up and running", loop + 1)
+ self.__logger.debug(
+ "try %s: Cloudify Manager isn't up and running \n%s",
+ loop + 1, traceback.format_exc())
time.sleep(30)
else:
self.__logger.error("Cloudify Manager isn't up and running")
return 1
self.__logger.info("Cloudify Manager is up and running")
return 0
+
+ def put_private_key(self):
+ """Put private keypair in manager"""
+ self.__logger.info("Put private keypair in manager")
+ scpc = scp.SCPClient(self.ssh.get_transport())
+ scpc.put(self.key_filename, remote_path='~/cloudify_ims.pem')
+ (_, stdout, stderr) = self.ssh.exec_command(
+ "sudo docker cp ~/cloudify_ims.pem "
+ "cfy_manager_local:/etc/cloudify/ && "
+ "sudo docker exec cfy_manager_local "
+ "chmod 444 /etc/cloudify/cloudify_ims.pem")
+ self.__logger.debug("output:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("error:\n%s", stderr.read().decode("utf-8"))
+
+ def upload_cfy_plugins(self, yaml, wgn):
+ """Upload Cloudify plugins"""
+ (_, stdout, stderr) = self.ssh.exec_command(
+ "sudo docker exec cfy_manager_local "
+ f"cfy plugins upload -y {yaml} {wgn} && "
+ "sudo docker exec cfy_manager_local cfy status")
+ self.__logger.debug("output:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("error:\n%s", stderr.read().decode("utf-8"))
+
+ def kill_existing_execution(self, dep_name):
+ """kill existing execution"""
+ try:
+ self.__logger.info('Deleting the current deployment')
+ exec_list = self.cfy_client.executions.list()
+ for execution in exec_list:
+ if execution['status'] == "started":
+ try:
+ self.cfy_client.executions.cancel(
+ execution['id'], force=True)
+ except Exception: # pylint: disable=broad-except
+ self.__logger.warning("Can't cancel the current exec")
+ execution = self.cfy_client.executions.start(
+ dep_name, 'uninstall', parameters=dict(ignore_failure=True))
+ wait_for_execution(self.cfy_client, execution, self.__logger)
+ self.cfy_client.deployments.delete(dep_name)
+ time.sleep(10)
+ self.cfy_client.blueprints.delete(dep_name)
+ except Exception: # pylint: disable=broad-except
+ self.__logger.exception("Some issue during the undeployment ..")
+
+
+def wait_for_execution(client, execution, logger, timeout=3600, ):
+ """Wait for a workflow execution on Cloudify Manager."""
+ # if execution already ended - return without waiting
+ if execution.status in Execution.END_STATES:
+ return execution
+
+ if timeout is not None:
+ deadline = time.time() + timeout
+
+ # Poll for execution status and execution logs, until execution ends
+ # and we receive an event of type in WORKFLOW_END_TYPES
+ offset = 0
+ batch_size = 50
+ event_list = []
+ execution_ended = False
+ while True:
+ event_list = client.events.list(
+ execution_id=execution.id,
+ _offset=offset,
+ _size=batch_size,
+ include_logs=True,
+ sort='@timestamp').items
+
+ offset = offset + len(event_list)
+ for event in event_list:
+ logger.debug(event.get('message'))
+
+ if timeout is not None:
+ if time.time() > deadline:
+ raise RuntimeError(
+ 'execution of operation {execution.workflow_id} for '
+ 'deployment {execution.deployment_id} timed out')
+ # update the remaining timeout
+ timeout = deadline - time.time()
+
+ if not execution_ended:
+ execution = client.executions.get(execution.id)
+ execution_ended = execution.status in Execution.END_STATES
+
+ if execution_ended:
+ break
+
+ time.sleep(5)
+
+ return execution
+
+
+def get_execution_id(client, deployment_id):
+ """
+ Get the execution id of a env preparation.
+
+ network, security group, fip, VM creation
+ """
+ executions = client.executions.list(deployment_id=deployment_id)
+ for execution in executions:
+ if execution.workflow_id == 'create_deployment_environment':
+ return execution
+ raise RuntimeError('Failed to get create_deployment_environment '
+ 'workflow execution.'
+ f'Available executions: {executions}')
diff --git a/functest/core/singlevm.py b/functest/core/singlevm.py
index ec7f967ec..4bce516d3 100644
--- a/functest/core/singlevm.py
+++ b/functest/core/singlevm.py
@@ -39,7 +39,7 @@ class VmReady1(tenantnetwork.TenantNetwork1):
# pylint: disable=too-many-instance-attributes
__logger = logging.getLogger(__name__)
- filename = '/home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.img'
+ filename = '/home/opnfv/functest/images/cirros-0.6.1-x86_64-disk.img'
image_format = 'qcow2'
extra_properties = {}
filename_alt = filename
@@ -59,7 +59,7 @@ class VmReady1(tenantnetwork.TenantNetwork1):
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = 'vmready1'
- super(VmReady1, self).__init__(**kwargs)
+ super().__init__(**kwargs)
self.image = None
self.flavor = None
@@ -80,19 +80,18 @@ class VmReady1(tenantnetwork.TenantNetwork1):
functest_utils.convert_ini_to_dict(
env.get('IMAGE_PROPERTIES')))
extra_properties.update(
- getattr(config.CONF, '{}_extra_properties'.format(
- self.case_name), {}))
+ getattr(config.CONF, f'{self.case_name}_extra_properties', {}))
image = self.cloud.create_image(
- name if name else '{}-img_{}'.format(self.case_name, self.guid),
+ name if name else f'{self.case_name}-img_{self.guid}',
filename=getattr(
- config.CONF, '{}_image'.format(self.case_name),
+ config.CONF, f'{self.case_name}_image',
self.filename),
meta=extra_properties,
disk_format=getattr(
- config.CONF, '{}_image_format'.format(self.case_name),
+ config.CONF, f'{self.case_name}_image_format',
self.image_format),
visibility=getattr(
- config.CONF, '{}_visibility'.format(self.case_name),
+ config.CONF, f'{self.case_name}_visibility',
self.visibility),
wait=True)
self.__logger.debug("image: %s", image)
@@ -115,20 +114,18 @@ class VmReady1(tenantnetwork.TenantNetwork1):
functest_utils.convert_ini_to_dict(
env.get('IMAGE_PROPERTIES')))
extra_alt_properties.update(
- getattr(config.CONF, '{}_extra_alt_properties'.format(
- self.case_name), {}))
+ getattr(config.CONF, f'{self.case_name}_extra_alt_properties', {}))
image = self.cloud.create_image(
- name if name else '{}-img_alt_{}'.format(
- self.case_name, self.guid),
+ name if name else f'{self.case_name}-img_alt_{self.guid}',
filename=getattr(
- config.CONF, '{}_image_alt'.format(self.case_name),
+ config.CONF, f'{self.case_name}_image_alt',
self.filename_alt),
meta=extra_alt_properties,
disk_format=getattr(
- config.CONF, '{}_image_alt_format'.format(self.case_name),
+ config.CONF, f'{self.case_name}_image_alt_format',
self.image_format),
visibility=getattr(
- config.CONF, '{}_visibility'.format(self.case_name),
+ config.CONF, f'{self.case_name}_visibility',
self.visibility),
wait=True)
self.__logger.debug("image: %s", image)
@@ -146,12 +143,12 @@ class VmReady1(tenantnetwork.TenantNetwork1):
"""
assert self.orig_cloud
flavor = self.orig_cloud.create_flavor(
- name if name else '{}-flavor_{}'.format(self.case_name, self.guid),
- getattr(config.CONF, '{}_flavor_ram'.format(self.case_name),
+ name if name else f'{self.case_name}-flavor_{self.guid}',
+ getattr(config.CONF, f'{self.case_name}_flavor_ram',
self.flavor_ram),
- getattr(config.CONF, '{}_flavor_vcpus'.format(self.case_name),
+ getattr(config.CONF, f'{self.case_name}_flavor_vcpus',
self.flavor_vcpus),
- getattr(config.CONF, '{}_flavor_disk'.format(self.case_name),
+ getattr(config.CONF, f'{self.case_name}_flavor_disk',
self.flavor_disk))
self.__logger.debug("flavor: %s", flavor)
flavor_extra_specs = self.flavor_extra_specs.copy()
@@ -161,7 +158,7 @@ class VmReady1(tenantnetwork.TenantNetwork1):
env.get('FLAVOR_EXTRA_SPECS')))
flavor_extra_specs.update(
getattr(config.CONF,
- '{}_flavor_extra_specs'.format(self.case_name), {}))
+ f'{self.case_name}_flavor_extra_specs', {}))
self.orig_cloud.set_flavor_specs(flavor.id, flavor_extra_specs)
return flavor
@@ -177,13 +174,12 @@ class VmReady1(tenantnetwork.TenantNetwork1):
"""
assert self.orig_cloud
flavor = self.orig_cloud.create_flavor(
- name if name else '{}-flavor_alt_{}'.format(
- self.case_name, self.guid),
- getattr(config.CONF, '{}_flavor_alt_ram'.format(self.case_name),
+ name if name else f'{self.case_name}-flavor_alt_{self.guid}',
+ getattr(config.CONF, f'{self.case_name}_flavor_alt_ram',
self.flavor_alt_ram),
- getattr(config.CONF, '{}_flavor_alt_vcpus'.format(self.case_name),
+ getattr(config.CONF, f'{self.case_name}_flavor_alt_vcpus',
self.flavor_alt_vcpus),
- getattr(config.CONF, '{}_flavor_alt_disk'.format(self.case_name),
+ getattr(config.CONF, f'{self.case_name}_flavor_alt_disk',
self.flavor_alt_disk))
self.__logger.debug("flavor: %s", flavor)
flavor_alt_extra_specs = self.flavor_alt_extra_specs.copy()
@@ -193,7 +189,7 @@ class VmReady1(tenantnetwork.TenantNetwork1):
env.get('FLAVOR_EXTRA_SPECS')))
flavor_alt_extra_specs.update(
getattr(config.CONF,
- '{}_flavor_alt_extra_specs'.format(self.case_name), {}))
+ f'{self.case_name}_flavor_alt_extra_specs', {}))
self.orig_cloud.set_flavor_specs(
flavor.id, flavor_alt_extra_specs)
return flavor
@@ -210,14 +206,16 @@ class VmReady1(tenantnetwork.TenantNetwork1):
"""
assert self.cloud
vm1 = self.cloud.create_server(
- name if name else '{}-vm_{}'.format(self.case_name, self.guid),
+ name if name else f'{self.case_name}-vm_{self.guid}',
image=self.image.id, flavor=self.flavor.id,
- auto_ip=False, network=self.network.id,
+ auto_ip=False,
+ network=self.network.id if self.network else env.get(
+ "EXTERNAL_NETWORK"),
timeout=self.create_server_timeout, wait=True, **kwargs)
self.__logger.debug("vm: %s", vm1)
return vm1
- def check_regex_in_console(self, name, regex=' login: ', loop=1):
+ def check_regex_in_console(self, name, regex=' login: ', loop=6):
"""Wait for specific message in console
Returns: True or False on errors
@@ -227,16 +225,52 @@ class VmReady1(tenantnetwork.TenantNetwork1):
console = self.cloud.get_server_console(name)
self.__logger.debug("console: \n%s", console)
if re.search(regex, console):
- self.__logger.debug("regex found: ''%s' in console", regex)
- return True
- else:
self.__logger.debug(
- "try %s: cannot find regex '%s' in console",
- iloop + 1, regex)
- time.sleep(10)
+ "regex found: '%s' in console\n%s", regex, console)
+ return True
+ self.__logger.debug(
+ "try %s: cannot find regex '%s' in console\n%s",
+ iloop + 1, regex, console)
+ time.sleep(10)
self.__logger.error("cannot find regex '%s' in console", regex)
return False
+ def clean_orphan_security_groups(self):
+ """Clean all security groups which are not owned by an existing tenant
+
+ It lists all orphan security groups in use as debug to avoid
+ misunderstanding the testcase results (it could happen if cloud admin
+ removes accounts without cleaning the virtual machines)
+ """
+ sec_groups = self.orig_cloud.list_security_groups()
+ for sec_group in sec_groups:
+ if not sec_group.tenant_id:
+ continue
+ if not self.orig_cloud.get_project(sec_group.tenant_id):
+ self.__logger.debug("Cleaning security group %s", sec_group.id)
+ try:
+ self.orig_cloud.delete_security_group(sec_group.id)
+ except Exception: # pylint: disable=broad-except
+ self.__logger.debug(
+ "Orphan security group %s in use", sec_group.id)
+
+ def count_hypervisors(self):
+ """Count hypervisors."""
+ if env.get('SKIP_DOWN_HYPERVISORS').lower() == 'false':
+ return len(self.orig_cloud.list_hypervisors())
+ return self.count_active_hypervisors()
+
+ def count_active_hypervisors(self):
+ """Count all hypervisors which are up."""
+ compute_cnt = 0
+ for hypervisor in self.orig_cloud.list_hypervisors():
+ if hypervisor['state'] == 'up':
+ compute_cnt += 1
+ else:
+ self.__logger.warning(
+ "%s is down", hypervisor['hypervisor_hostname'])
+ return compute_cnt
+
def run(self, **kwargs):
"""Boot the new VM
@@ -251,7 +285,7 @@ class VmReady1(tenantnetwork.TenantNetwork1):
status = testcase.TestCase.EX_RUN_ERROR
try:
assert self.cloud
- assert super(VmReady1, self).run(
+ assert super().run(
**kwargs) == testcase.TestCase.EX_OK
self.image = self.publish_image()
self.flavor = self.create_flavor()
@@ -268,11 +302,13 @@ class VmReady1(tenantnetwork.TenantNetwork1):
try:
assert self.orig_cloud
assert self.cloud
- super(VmReady1, self).clean()
+ super().clean()
if self.image:
self.cloud.delete_image(self.image.id)
if self.flavor:
self.orig_cloud.delete_flavor(self.flavor.id)
+ if env.get('CLEAN_ORPHAN_SECURITY_GROUPS').lower() == 'true':
+ self.clean_orphan_security_groups()
except Exception: # pylint: disable=broad-except
self.__logger.exception("Cannot clean all resources")
@@ -292,7 +328,7 @@ class VmReady2(VmReady1):
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = 'vmready2'
- super(VmReady2, self).__init__(**kwargs)
+ super().__init__(**kwargs)
try:
assert self.orig_cloud
self.project = tenantnetwork.NewProject(
@@ -306,7 +342,7 @@ class VmReady2(VmReady1):
def clean(self):
try:
- super(VmReady2, self).clean()
+ super().clean()
assert self.project
self.project.clean()
except Exception: # pylint: disable=broad-except
@@ -329,11 +365,13 @@ class SingleVm1(VmReady1):
ssh_connect_timeout = 1
ssh_connect_loops = 6
create_floating_ip_timeout = 120
+ check_console_loop = 6
+ check_console_regex = ' login: '
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = 'singlevm1'
- super(SingleVm1, self).__init__(**kwargs)
+ super().__init__(**kwargs)
self.sshvm = None
self.sec = None
self.fip = None
@@ -351,14 +389,15 @@ class SingleVm1(VmReady1):
"""
assert self.cloud
self.keypair = self.cloud.create_keypair(
- '{}-kp_{}'.format(self.case_name, self.guid))
+ f'{self.case_name}-kp_{self.guid}')
self.__logger.debug("keypair: %s", self.keypair)
- self.__logger.debug("private_key: %s", self.keypair.private_key)
- with open(self.key_filename, 'w') as private_key_file:
+ self.__logger.debug("private_key:\n%s", self.keypair.private_key)
+ with open(
+ self.key_filename, 'w', encoding='utf-8') as private_key_file:
private_key_file.write(self.keypair.private_key)
self.sec = self.cloud.create_security_group(
- '{}-sg_{}'.format(self.case_name, self.guid),
- 'created by OPNFV Functest ({})'.format(self.case_name))
+ f'{self.case_name}-sg_{self.guid}',
+ f'created by OPNFV Functest ({self.case_name})')
self.cloud.create_security_group_rule(
self.sec.id, port_range_min='22', port_range_max='22',
protocol='tcp', direction='ingress')
@@ -376,10 +415,12 @@ class SingleVm1(VmReady1):
- None on error
"""
assert vm1
- fip = self.cloud.create_floating_ip(
- network=self.ext_net.id, server=vm1, wait=True,
- timeout=self.create_floating_ip_timeout)
- self.__logger.debug("floating_ip: %s", fip)
+ fip = None
+ if env.get('NO_TENANT_NETWORK').lower() != 'true':
+ fip = self.cloud.create_floating_ip(
+ network=self.ext_net.id, server=vm1, wait=True,
+ timeout=self.create_floating_ip_timeout)
+ self.__logger.debug("floating_ip: %s", fip)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
for loop in range(self.ssh_connect_loops):
@@ -387,20 +428,20 @@ class SingleVm1(VmReady1):
p_console = self.cloud.get_server_console(vm1)
self.__logger.debug("vm console: \n%s", p_console)
ssh.connect(
- fip.floating_ip_address,
+ fip.floating_ip_address if fip else vm1.public_v4,
username=getattr(
config.CONF,
- '{}_image_user'.format(self.case_name), self.username),
+ f'{self.case_name}_image_user', self.username),
key_filename=self.key_filename,
timeout=getattr(
config.CONF,
- '{}_vm_ssh_connect_timeout'.format(self.case_name),
+ f'{self.case_name}_vm_ssh_connect_timeout',
self.ssh_connect_timeout))
break
except Exception as exc: # pylint: disable=broad-except
self.__logger.debug(
"try %s: cannot connect to %s: %s", loop + 1,
- fip.floating_ip_address, exc)
+ fip.floating_ip_address if fip else vm1.public_v4, exc)
time.sleep(9)
else:
self.__logger.error(
@@ -416,8 +457,8 @@ class SingleVm1(VmReady1):
Returns: echo exit codes
"""
(_, stdout, stderr) = self.ssh.exec_command('echo Hello World')
- self.__logger.debug("output:\n%s", stdout.read())
- self.__logger.debug("error:\n%s", stderr.read())
+ self.__logger.debug("output:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("error:\n%s", stderr.read().decode("utf-8"))
return stdout.channel.recv_exit_status()
def run(self, **kwargs):
@@ -436,16 +477,19 @@ class SingleVm1(VmReady1):
status = testcase.TestCase.EX_RUN_ERROR
try:
assert self.cloud
- assert super(SingleVm1, self).run(
+ assert super().run(
**kwargs) == testcase.TestCase.EX_OK
self.result = 0
self.prepare()
self.sshvm = self.boot_vm(
key_name=self.keypair.id, security_groups=[self.sec.id])
- (self.fip, self.ssh) = self.connect(self.sshvm)
- if not self.execute():
- self.result = 100
- status = testcase.TestCase.EX_OK
+ if self.check_regex_in_console(
+ self.sshvm.name, regex=self.check_console_regex,
+ loop=self.check_console_loop):
+ (self.fip, self.ssh) = self.connect(self.sshvm)
+ if not self.execute():
+ self.result = 100
+ status = testcase.TestCase.EX_OK
except Exception: # pylint: disable=broad-except
self.__logger.exception('Cannot run %s', self.case_name)
finally:
@@ -464,7 +508,7 @@ class SingleVm1(VmReady1):
self.cloud.delete_security_group(self.sec.id)
if self.keypair:
self.cloud.delete_keypair(self.keypair.name)
- super(SingleVm1, self).clean()
+ super().clean()
except Exception: # pylint: disable=broad-except
self.__logger.exception("Cannot clean all resources")
@@ -484,7 +528,7 @@ class SingleVm2(SingleVm1):
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = 'singlevm2'
- super(SingleVm2, self).__init__(**kwargs)
+ super().__init__(**kwargs)
try:
assert self.orig_cloud
self.project = tenantnetwork.NewProject(
@@ -498,7 +542,7 @@ class SingleVm2(SingleVm1):
def clean(self):
try:
- super(SingleVm2, self).clean()
+ super().clean()
assert self.project
self.project.clean()
except Exception: # pylint: disable=broad-except
diff --git a/functest/core/tenantnetwork.py b/functest/core/tenantnetwork.py
index e03740767..3670dbe8a 100644
--- a/functest/core/tenantnetwork.py
+++ b/functest/core/tenantnetwork.py
@@ -25,13 +25,15 @@ import uuid
import os_client_config
import shade
+from tempest.lib.common.utils import data_utils
from xtesting.core import testcase
from functest.utils import config
from functest.utils import env
+from functest.utils import functest_utils
-class NewProject(object):
+class NewProject():
"""Ease creating new projects/users"""
# pylint: disable=too-many-instance-attributes
@@ -46,7 +48,6 @@ class NewProject(object):
self.user = None
self.password = None
self.domain = None
- self.role = None
self.role_name = None
self.default_member = env.get('NEW_USER_ROLE')
@@ -54,18 +55,18 @@ class NewProject(object):
"""Create projects/users"""
assert self.orig_cloud
assert self.case_name
- self.password = str(uuid.uuid4())
+ self.password = data_utils.rand_password().replace('%', '!')
+ self.__logger.debug("password: %s", self.password)
self.domain = self.orig_cloud.get_domain(
name_or_id=self.orig_cloud.auth.get(
"project_domain_name", "Default"))
self.project = self.orig_cloud.create_project(
- name='{}-project_{}'.format(self.case_name[:18], self.guid),
- description="Created by OPNFV Functest: {}".format(
- self.case_name),
+ name=f'{self.case_name[:18]}-project_{self.guid}',
+ description=f"Created by OPNFV Functest: {self.case_name}",
domain_id=self.domain.id)
self.__logger.debug("project: %s", self.project)
self.user = self.orig_cloud.create_user(
- name='{}-user_{}'.format(self.case_name, self.guid),
+ name=f'{self.case_name}-user_{self.guid}',
password=self.password,
domain_id=self.domain.id)
self.__logger.debug("user: %s", self.user)
@@ -75,12 +76,12 @@ class NewProject(object):
elif self.orig_cloud.get_role(self.default_member.lower()):
self.role_name = self.default_member.lower()
else:
- raise Exception("Cannot detect {}".format(self.default_member))
+ raise Exception(f"Cannot detect {self.default_member}")
except Exception: # pylint: disable=broad-except
self.__logger.info("Creating default role %s", self.default_member)
- self.role = self.orig_cloud.create_role(self.default_member)
- self.role_name = self.role.name
- self.__logger.debug("role: %s", self.role)
+ role = self.orig_cloud.create_role(self.default_member)
+ self.role_name = role.name
+ self.__logger.debug("role: %s", role)
self.orig_cloud.grant_role(
self.role_name, user=self.user.id, project=self.project.id,
domain=self.domain.id)
@@ -96,6 +97,21 @@ class NewProject(object):
cloud_config=osconfig.get_one_cloud())
self.__logger.debug("new cloud %s", self.cloud.auth)
+ def get_environ(self):
+ "Get new environ"
+ environ = dict(
+ os.environ,
+ OS_USERNAME=self.user.name,
+ OS_PROJECT_NAME=self.project.name,
+ OS_PROJECT_ID=self.project.id,
+ OS_PASSWORD=self.password)
+ try:
+ del environ['OS_TENANT_NAME']
+ del environ['OS_TENANT_ID']
+ except Exception: # pylint: disable=broad-except
+ pass
+ return environ
+
def clean(self):
"""Remove projects/users"""
try:
@@ -104,8 +120,6 @@ class NewProject(object):
self.orig_cloud.delete_user(self.user.id)
if self.project:
self.orig_cloud.delete_project(self.project.id)
- if self.role:
- self.orig_cloud.delete_role(self.role.id)
secgroups = self.orig_cloud.list_security_groups(
filters={'name': 'default',
'project_id': self.project.id})
@@ -135,21 +149,24 @@ class TenantNetwork1(testcase.TestCase):
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = 'tenantnetwork1'
- super(TenantNetwork1, self).__init__(**kwargs)
- self.res_dir = os.path.join(
- getattr(config.CONF, 'dir_results'), self.case_name)
+ super().__init__(**kwargs)
+ self.dir_results = os.path.join(getattr(config.CONF, 'dir_results'))
+ self.res_dir = os.path.join(self.dir_results, self.case_name)
+ self.output_log_name = 'functest.log'
+ self.output_debug_log_name = 'functest.debug.log'
+ self.ext_net = None
try:
cloud_config = os_client_config.get_config()
self.cloud = self.orig_cloud = shade.OpenStackCloud(
cloud_config=cloud_config)
except Exception: # pylint: disable=broad-except
self.cloud = self.orig_cloud = None
- self.ext_net = None
self.__logger.exception("Cannot connect to Cloud")
- try:
- self.ext_net = self.get_external_network(self.cloud)
- except Exception: # pylint: disable=broad-except
- self.__logger.exception("Cannot get the external network")
+ if env.get('NO_TENANT_NETWORK').lower() != 'true':
+ try:
+ self.ext_net = self.get_external_network(self.cloud)
+ except Exception: # pylint: disable=broad-except
+ self.__logger.exception("Cannot get the external network")
self.guid = str(uuid.uuid4())
self.network = None
self.subnet = None
@@ -186,7 +203,7 @@ class TenantNetwork1(testcase.TestCase):
@staticmethod
def get_public_auth_url(cloud):
"""Get Keystone public endpoint"""
- keystone_id = cloud.search_services('keystone')[0].id
+ keystone_id = functest_utils.search_services(cloud, 'keystone')[0].id
endpoint = cloud.search_endpoints(
filters={'interface': 'public',
'service_id': keystone_id})[0].url
@@ -201,17 +218,18 @@ class TenantNetwork1(testcase.TestCase):
Raises: expection on error
"""
assert self.cloud
- assert self.ext_net
+ if env.get('NO_TENANT_NETWORK').lower() != 'true':
+ assert self.ext_net
provider = {}
- if hasattr(config.CONF, '{}_network_type'.format(self.case_name)):
+ if hasattr(config.CONF, f'{self.case_name}_network_type'):
provider["network_type"] = getattr(
- config.CONF, '{}_network_type'.format(self.case_name))
- if hasattr(config.CONF, '{}_physical_network'.format(self.case_name)):
+ config.CONF, f'{self.case_name}_network_type')
+ if hasattr(config.CONF, f'{self.case_name}_physical_network'):
provider["physical_network"] = getattr(
- config.CONF, '{}_physical_network'.format(self.case_name))
- if hasattr(config.CONF, '{}_segmentation_id'.format(self.case_name)):
+ config.CONF, f'{self.case_name}_physical_network')
+ if hasattr(config.CONF, f'{self.case_name}_segmentation_id'):
provider["segmentation_id"] = getattr(
- config.CONF, '{}_segmentation_id'.format(self.case_name))
+ config.CONF, f'{self.case_name}_segmentation_id')
domain = self.orig_cloud.get_domain(
name_or_id=self.orig_cloud.auth.get(
"project_domain_name", "Default"))
@@ -219,24 +237,24 @@ class TenantNetwork1(testcase.TestCase):
self.cloud.auth['project_name'],
domain_id=domain.id)
self.network = self.orig_cloud.create_network(
- '{}-net_{}'.format(self.case_name, self.guid),
+ f'{self.case_name}-net_{self.guid}',
provider=provider, project_id=project.id,
shared=self.shared_network)
self.__logger.debug("network: %s", self.network)
self.subnet = self.cloud.create_subnet(
self.network.id,
- subnet_name='{}-subnet_{}'.format(self.case_name, self.guid),
+ subnet_name=f'{self.case_name}-subnet_{self.guid}',
cidr=getattr(
- config.CONF, '{}_private_subnet_cidr'.format(self.case_name),
+ config.CONF, f'{self.case_name}_private_subnet_cidr',
self.cidr),
enable_dhcp=True,
dns_nameservers=[env.get('NAMESERVER')])
self.__logger.debug("subnet: %s", self.subnet)
self.router = self.cloud.create_router(
- name='{}-router_{}'.format(self.case_name, self.guid),
- ext_gateway_net_id=self.ext_net.id)
+ name=f'{self.case_name}-router_{self.guid}',
+ ext_gateway_net_id=self.ext_net.id if self.ext_net else None)
self.__logger.debug("router: %s", self.router)
self.cloud.add_router_interface(self.router, subnet_id=self.subnet.id)
@@ -245,7 +263,8 @@ class TenantNetwork1(testcase.TestCase):
try:
assert self.cloud
self.start_time = time.time()
- self.create_network_resources()
+ if env.get('NO_TENANT_NETWORK').lower() != 'true':
+ self.create_network_resources()
self.result = 100
status = testcase.TestCase.EX_OK
except Exception: # pylint: disable=broad-except
@@ -286,7 +305,7 @@ class TenantNetwork2(TenantNetwork1):
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = 'tenantnetwork2'
- super(TenantNetwork2, self).__init__(**kwargs)
+ super().__init__(**kwargs)
try:
assert self.cloud
self.project = NewProject(
@@ -300,7 +319,7 @@ class TenantNetwork2(TenantNetwork1):
def clean(self):
try:
- super(TenantNetwork2, self).clean()
+ super().clean()
assert self.project
self.project.clean()
except Exception: # pylint: disable=broad-except
diff --git a/functest/opnfv_tests/openstack/api/connection_check.py b/functest/opnfv_tests/openstack/api/connection_check.py
index a7a780f67..eaf9767c0 100644
--- a/functest/opnfv_tests/openstack/api/connection_check.py
+++ b/functest/opnfv_tests/openstack/api/connection_check.py
@@ -16,15 +16,27 @@ import os_client_config
import shade
from xtesting.core import testcase
+from functest.utils import env
+from functest.utils import functest_utils
+
class ConnectionCheck(testcase.TestCase):
"""Perform simplest queries"""
__logger = logging.getLogger(__name__)
+ func_list = [
+ "get_network_extensions", "list_aggregates", "list_domains",
+ "list_endpoints", "list_floating_ip_pools", "list_floating_ips",
+ "list_hypervisors", "list_keypairs", "list_networks", "list_ports",
+ "list_role_assignments", "list_roles", "list_routers", "list_servers",
+ "list_subnets"]
+
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = 'connection_check'
- super(ConnectionCheck, self).__init__(**kwargs)
+ super().__init__(**kwargs)
+ self.output_log_name = 'functest.log'
+ self.output_debug_log_name = 'functest.debug.log'
try:
cloud_config = os_client_config.get_config()
self.cloud = shade.OpenStackCloud(cloud_config=cloud_config)
@@ -32,19 +44,26 @@ class ConnectionCheck(testcase.TestCase):
self.cloud = None
def run(self, **kwargs):
+ # pylint: disable=protected-access
"""Run all read operations to check connections"""
status = testcase.TestCase.EX_RUN_ERROR
try:
assert self.cloud
self.start_time = time.time()
- for func in ["list_aggregates", "list_domains", "list_endpoints",
- "list_floating_ip_pools", "list_floating_ips",
- "list_hypervisors", "list_keypairs", "list_networks",
- "list_ports", "list_role_assignments", "list_roles",
- "list_routers", "list_servers", "list_services",
- "list_subnets"]:
+ self.__logger.debug(
+ "list_services: %s", functest_utils.list_services(self.cloud))
+ if env.get('NO_TENANT_NETWORK').lower() == 'true':
+ self.func_list.remove("list_floating_ip_pools")
+ self.func_list.remove("list_floating_ips")
+ self.func_list.remove("list_routers")
+ for func in self.func_list:
self.__logger.debug(
"%s: %s", func, getattr(self.cloud, func)())
+ data = self.cloud._network_client.get("/service-providers.json")
+ self.__logger.debug(
+ "list_service_providers: %s",
+ self.cloud._get_and_munchify('service_providers', data))
+ functest_utils.get_openstack_version(self.cloud)
self.result = 100
status = testcase.TestCase.EX_OK
except Exception: # pylint: disable=broad-except
diff --git a/functest/opnfv_tests/openstack/barbican/barbican.py b/functest/opnfv_tests/openstack/barbican/barbican.py
index b9488c2b6..706304bbf 100644
--- a/functest/opnfv_tests/openstack/barbican/barbican.py
+++ b/functest/opnfv_tests/openstack/barbican/barbican.py
@@ -9,8 +9,6 @@
# pylint: disable=missing-docstring
-import logging
-
from six.moves import configparser
from functest.opnfv_tests.openstack.tempest import tempest
@@ -18,10 +16,8 @@ from functest.opnfv_tests.openstack.tempest import tempest
class Barbican(tempest.TempestCommon):
- __logger = logging.getLogger(__name__)
-
def configure(self, **kwargs):
- super(Barbican, self).configure(**kwargs)
+ super().configure(**kwargs)
rconfig = configparser.RawConfigParser()
rconfig.read(self.conf_file)
if not rconfig.has_section('auth'):
@@ -36,6 +32,6 @@ class Barbican(tempest.TempestCommon):
if not rconfig.has_section('image-feature-enabled'):
rconfig.add_section('image-feature-enabled')
rconfig.set('image-feature-enabled', 'api_v1', False)
- with open(self.conf_file, 'wb') as config_file:
+ with open(self.conf_file, 'w', encoding='utf-8') as config_file:
rconfig.write(config_file)
self.backup_tempest_config(self.conf_file, self.res_dir)
diff --git a/functest/opnfv_tests/openstack/cinder/cinder_test.py b/functest/opnfv_tests/openstack/cinder/cinder_test.py
index bbed9a64f..7d8c0a0bd 100644
--- a/functest/opnfv_tests/openstack/cinder/cinder_test.py
+++ b/functest/opnfv_tests/openstack/cinder/cinder_test.py
@@ -35,7 +35,7 @@ class CinderCheck(singlevm.SingleVm2):
"""Initialize testcase."""
if "case_name" not in kwargs:
kwargs["case_name"] = "cinder_test"
- super(CinderCheck, self).__init__(**kwargs)
+ super().__init__(**kwargs)
self.logger = logging.getLogger(__name__)
self.vm2 = None
self.fip2 = None
@@ -52,14 +52,14 @@ class CinderCheck(singlevm.SingleVm2):
return self._write_data() or self._read_data()
def prepare(self):
- super(CinderCheck, self).prepare()
+ super().prepare()
self.vm2 = self.boot_vm(
- '{}-vm2_{}'.format(self.case_name, self.guid),
+ f'{self.case_name}-vm2_{self.guid}',
key_name=self.keypair.id,
security_groups=[self.sec.id])
(self.fip2, self.ssh2) = self.connect(self.vm2)
self.volume = self.cloud.create_volume(
- name='{}-volume_{}'.format(self.case_name, self.guid), size='2',
+ name=f'{self.case_name}-volume_{self.guid}', size='2',
timeout=self.volume_timeout, wait=True)
def _write_data(self):
@@ -76,9 +76,11 @@ class CinderCheck(singlevm.SingleVm2):
return testcase.TestCase.EX_RUN_ERROR
self.logger.debug("ssh: %s", self.ssh)
(_, stdout, stderr) = self.ssh.exec_command(
- "sh ~/write_data.sh {}".format(env.get('VOLUME_DEVICE_NAME')))
- self.logger.debug("volume_write stdout: %s", stdout.read())
- self.logger.debug("volume_write stderr: %s", stderr.read())
+ f"sh ~/write_data.sh {env.get('VOLUME_DEVICE_NAME')}")
+ self.logger.debug(
+ "volume_write stdout: %s", stdout.read().decode("utf-8"))
+ self.logger.debug(
+ "volume_write stderr: %s", stderr.read().decode("utf-8"))
# Detach volume from VM 1
self.logger.info("Detach volume from VM 1")
self.cloud.detach_volume(
@@ -102,9 +104,11 @@ class CinderCheck(singlevm.SingleVm2):
return testcase.TestCase.EX_RUN_ERROR
self.logger.debug("ssh: %s", self.ssh2)
(_, stdout, stderr) = self.ssh2.exec_command(
- "sh ~/read_data.sh {}".format(env.get('VOLUME_DEVICE_NAME')))
- self.logger.debug("read volume stdout: %s", stdout.read())
- self.logger.debug("read volume stderr: %s", stderr.read())
+ f"sh ~/read_data.sh {env.get('VOLUME_DEVICE_NAME')}")
+ self.logger.debug(
+ "read volume stdout: %s", stdout.read().decode("utf-8"))
+ self.logger.debug(
+ "read volume stderr: %s", stderr.read().decode("utf-8"))
self.logger.info("Detach volume from VM 2")
self.cloud.detach_volume(
self.vm2, self.volume, timeout=self.volume_timeout)
@@ -120,4 +124,4 @@ class CinderCheck(singlevm.SingleVm2):
self.cloud.delete_floating_ip(self.fip2.id)
if self.volume:
self.cloud.delete_volume(self.volume.id)
- super(CinderCheck, self).clean()
+ super().clean()
diff --git a/functest/opnfv_tests/openstack/cinder/write_data.sh b/functest/opnfv_tests/openstack/cinder/write_data.sh
index 6689309b9..16845ba31 100644
--- a/functest/opnfv_tests/openstack/cinder/write_data.sh
+++ b/functest/opnfv_tests/openstack/cinder/write_data.sh
@@ -15,7 +15,7 @@ echo "VOL_DEV_NAME: $VOL_DEV_NAME"
echo "$(lsblk -l -o NAME)"
if [ ! -z $(lsblk -l -o NAME | grep $VOL_DEV_NAME) ]; then
- sudo /usr/sbin/mkfs.ext4 -F /dev/$VOL_DEV_NAME
+ sudo mkfs.ext4 -F /dev/$VOL_DEV_NAME
sudo mount /dev/$VOL_DEV_NAME $DEST
sudo touch $DEST/new_data
if [ -f $DEST/new_data ]; then
diff --git a/functest/opnfv_tests/openstack/patrole/patrole.py b/functest/opnfv_tests/openstack/patrole/patrole.py
index 45378b6cd..88c42f269 100644
--- a/functest/opnfv_tests/openstack/patrole/patrole.py
+++ b/functest/opnfv_tests/openstack/patrole/patrole.py
@@ -9,8 +9,6 @@
# pylint: disable=missing-docstring
-import logging
-
from six.moves import configparser
from functest.opnfv_tests.openstack.tempest import tempest
@@ -18,23 +16,13 @@ from functest.opnfv_tests.openstack.tempest import tempest
class Patrole(tempest.TempestCommon):
- __logger = logging.getLogger(__name__)
-
def configure(self, **kwargs):
- super(Patrole, self).configure(**kwargs)
+ super().configure(**kwargs)
rconfig = configparser.RawConfigParser()
rconfig.read(self.conf_file)
- rconfig.add_section('rbac')
- rconfig.set('rbac', 'enable_rbac', True)
- rconfig.set('rbac', 'rbac_test_role', kwargs.get('role', 'admin'))
- with open(self.conf_file, 'wb') as config_file:
+ if not rconfig.has_section('rbac'):
+ rconfig.add_section('rbac')
+ rconfig.set('rbac', 'rbac_test_roles', kwargs.get('roles', 'admin'))
+ with open(self.conf_file, 'w', encoding='utf-8') as config_file:
rconfig.write(config_file)
self.backup_tempest_config(self.conf_file, self.res_dir)
-
- def run(self, **kwargs):
- for exclude in kwargs.get('excludes', []):
- kwargs['mode'] = "{}(?!.*{})".format(
- kwargs.get('mode', ''), exclude)
- kwargs['mode'] = '{}(?=patrole_tempest_plugin.tests.api.({}))'.format(
- kwargs['mode'], '|'.join(kwargs.get('includes', [])))
- return super(Patrole, self).run(**kwargs)
diff --git a/functest/opnfv_tests/openstack/rally/blacklist.txt b/functest/opnfv_tests/openstack/rally/blacklist.txt
deleted file mode 100644
index 1ade43eaf..000000000
--- a/functest/opnfv_tests/openstack/rally/blacklist.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-scenario:
- -
- scenarios:
- - '^os-' # all scenarios
- tests:
- # Following test occasionally fails due to race condition issue on
- # quota manipulation in nova.
- # Ref: https://bugs.launchpad.net/nova/+bug/1552622
- - 'Quotas.nova_update_and_delete'
-
-functionality:
- -
- functions:
- - no_migration
- tests:
- - NovaServers.boot_and_live_migrate_server
- - NovaServers.boot_server_attach_created_volume_and_live_migrate
- - NovaServers.boot_server_from_volume_and_live_migrate
- - NovaServers.boot_and_migrate_server
- -
- functions:
- - no_net_trunk_service
- tests:
- - '^NeutronTrunk'
diff --git a/functest/opnfv_tests/openstack/rally/blacklist.yaml b/functest/opnfv_tests/openstack/rally/blacklist.yaml
new file mode 100644
index 000000000..e16b83ba6
--- /dev/null
+++ b/functest/opnfv_tests/openstack/rally/blacklist.yaml
@@ -0,0 +1,40 @@
+---
+scenario:
+
+functionality:
+ -
+ functions:
+ - block_migration
+ tests:
+ - NovaServers.boot_server_from_volume_and_live_migrate
+ -
+ functions:
+ - no_migration
+ tests:
+ - NovaServers.boot_and_live_migrate_server
+ - NovaServers.boot_server_attach_created_volume_and_live_migrate
+ - NovaServers.boot_server_from_volume_and_live_migrate
+ - NovaServers.boot_and_migrate_server
+ -
+ functions:
+ - no_net_trunk_service
+ tests:
+ - '^NeutronTrunk'
+ -
+ functions:
+ - no_floating_ip
+ tests:
+ - HeatStacks.create_and_delete_stack
+ - NovaServers.boot_and_associate_floating_ip
+ - NovaServers.boot_server_and_list_interfaces
+ - NovaServers.boot_server_associate_and_dissociate_floating_ip
+ - NeutronNetworks.create_and_delete_floating_ips
+ - NeutronNetworks.create_and_list_floating_ips
+ - NeutronNetworks.associate_and_dissociate_floating_ips
+ - VMTasks.dd_load_test
+ - NeutronNetworks.create_and_delete_routers
+ - NeutronNetworks.create_and_list_routers
+ - NeutronNetworks.create_and_show_routers
+ - NeutronNetworks.create_and_update_routers
+ - NeutronNetworks.set_and_clear_router_gateway
+ - Quotas.neutron_update
diff --git a/functest/opnfv_tests/openstack/rally/macro/macro.yaml b/functest/opnfv_tests/openstack/rally/macro/macro.yaml
index 48c0333e9..2536c92f0 100644
--- a/functest/opnfv_tests/openstack/rally/macro/macro.yaml
+++ b/functest/opnfv_tests/openstack/rally/macro/macro.yaml
@@ -95,3 +95,9 @@
disk_format: {{ type }}
image_location: {{ location }}
{%- endmacro %}
+
+{%- macro volume_service(version, service_type) %}
+ cinder:
+ version: {{ version }}
+ service_type: {{ service_type }}
+{%- endmacro %}
diff --git a/functest/opnfv_tests/openstack/rally/rally.py b/functest/opnfv_tests/openstack/rally/rally.py
index 1d7d75ff4..3d897e25d 100644
--- a/functest/opnfv_tests/openstack/rally/rally.py
+++ b/functest/opnfv_tests/openstack/rally/rally.py
@@ -11,7 +11,9 @@
"""Rally testcases implementation."""
from __future__ import division
+from __future__ import print_function
+import fileinput
import json
import logging
import os
@@ -23,15 +25,15 @@ import time
import pkg_resources
import prettytable
from ruamel.yaml import YAML
+import six
from six.moves import configparser
from xtesting.core import testcase
-from xtesting.energy import energy
import yaml
from functest.core import singlevm
-from functest.opnfv_tests.openstack.tempest import conf_utils
from functest.utils import config
from functest.utils import env
+from functest.utils import functest_utils
LOGGER = logging.getLogger(__name__)
@@ -39,32 +41,40 @@ LOGGER = logging.getLogger(__name__)
class RallyBase(singlevm.VmReady2):
"""Base class form Rally testcases implementation."""
- # pylint: disable=too-many-instance-attributes
- TESTS = ['authenticate', 'glance', 'cinder', 'gnocchi', 'heat',
- 'keystone', 'neutron', 'nova', 'quotas']
+ # pylint: disable=too-many-instance-attributes, too-many-public-methods
+ stests = ['authenticate', 'glance', 'cinder', 'gnocchi', 'heat',
+ 'keystone', 'neutron', 'nova', 'quotas', 'swift', 'barbican',
+ 'vm']
- RALLY_DIR = pkg_resources.resource_filename(
+ rally_conf_path = "/etc/rally/rally.conf"
+ rally_aar4_patch_path = pkg_resources.resource_filename(
+ 'functest', 'ci/rally_aarch64_patch.conf')
+ rally_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/openstack/rally')
- RALLY_SCENARIO_DIR = pkg_resources.resource_filename(
+ rally_scenario_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/openstack/rally/scenario')
- TEMPLATE_DIR = pkg_resources.resource_filename(
+ template_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/openstack/rally/scenario/templates')
- SUPPORT_DIR = pkg_resources.resource_filename(
+ support_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/openstack/rally/scenario/support')
- USERS_AMOUNT = 2
- TENANTS_AMOUNT = 3
- ITERATIONS_AMOUNT = 10
- CONCURRENCY = 4
- BLACKLIST_FILE = os.path.join(RALLY_DIR, "blacklist.txt")
- TASK_DIR = os.path.join(getattr(config.CONF, 'dir_rally_data'), 'task')
- TEMP_DIR = os.path.join(TASK_DIR, 'var')
+ users_amount = 2
+ tenants_amount = 3
+ iterations_amount = 10
+ concurrency = 4
+ volume_version = 3
+ volume_service_type = "volumev3"
+ blacklist_file = os.path.join(rally_dir, "blacklist.yaml")
+ task_dir = os.path.join(getattr(config.CONF, 'dir_rally_data'), 'task')
+ temp_dir = os.path.join(task_dir, 'var')
visibility = 'public'
shared_network = True
+ task_timeout = 3600
+ username = 'cirros'
def __init__(self, **kwargs):
"""Initialize RallyBase object."""
- super(RallyBase, self).__init__(**kwargs)
+ super().__init__(**kwargs)
assert self.orig_cloud
assert self.project
if self.orig_cloud.get_role("admin"):
@@ -84,32 +94,35 @@ class RallyBase(singlevm.VmReady2):
self.summary = []
self.scenario_dir = ''
self.smoke = None
- self.test_name = None
self.start_time = None
self.result = None
- self.details = None
self.compute_cnt = 0
self.flavor_alt = None
self.tests = []
self.run_cmd = ''
self.network_extensions = []
+ self.services = []
- def _build_task_args(self, test_file_name):
+ def build_task_args(self, test_name):
"""Build arguments for the Rally task."""
- task_args = {'service_list': [test_file_name]}
+ task_args = {'service_list': [test_name]}
task_args['image_name'] = str(self.image.name)
task_args['flavor_name'] = str(self.flavor.name)
task_args['flavor_alt_name'] = str(self.flavor_alt.name)
task_args['glance_image_location'] = str(self.filename)
task_args['glance_image_format'] = str(self.image_format)
- task_args['tmpl_dir'] = str(self.TEMPLATE_DIR)
- task_args['sup_dir'] = str(self.SUPPORT_DIR)
- task_args['users_amount'] = self.USERS_AMOUNT
- task_args['tenants_amount'] = self.TENANTS_AMOUNT
+ task_args['tmpl_dir'] = str(self.template_dir)
+ task_args['sup_dir'] = str(self.support_dir)
+ task_args['users_amount'] = self.users_amount
+ task_args['tenants_amount'] = self.tenants_amount
task_args['use_existing_users'] = False
- task_args['iterations'] = self.ITERATIONS_AMOUNT
- task_args['concurrency'] = self.CONCURRENCY
+ task_args['iterations'] = self.iterations_amount
+ task_args['concurrency'] = self.concurrency
task_args['smoke'] = self.smoke
+ task_args['volume_version'] = self.volume_version
+ task_args['volume_service_type'] = self.volume_service_type
+ task_args['block_migration'] = env.get("BLOCK_MIGRATION").lower()
+ task_args['username'] = self.username
if self.ext_net:
task_args['floating_network'] = str(self.ext_net.name)
@@ -119,14 +132,21 @@ class RallyBase(singlevm.VmReady2):
if self.network:
task_args['netid'] = str(self.network.id)
else:
- task_args['netid'] = ''
+ LOGGER.warning(
+ 'No tenant network created. '
+ 'Trying EXTERNAL_NETWORK as a fallback')
+ if env.get("EXTERNAL_NETWORK"):
+ network = self.cloud.get_network(env.get("EXTERNAL_NETWORK"))
+ task_args['netid'] = str(network.id) if network else ''
+ else:
+ task_args['netid'] = ''
return task_args
def _prepare_test_list(self, test_name):
"""Build the list of test cases to be executed."""
- test_yaml_file_name = 'opnfv-{}.yaml'.format(test_name)
- scenario_file_name = os.path.join(self.RALLY_SCENARIO_DIR,
+ test_yaml_file_name = f'opnfv-{test_name}.yaml'
+ scenario_file_name = os.path.join(self.rally_scenario_dir,
test_yaml_file_name)
if not os.path.exists(scenario_file_name):
@@ -134,19 +154,73 @@ class RallyBase(singlevm.VmReady2):
test_yaml_file_name)
if not os.path.exists(scenario_file_name):
- raise Exception("The scenario '%s' does not exist."
- % scenario_file_name)
+ raise Exception(
+ f"The scenario '{scenario_file_name}' does not exist.")
LOGGER.debug('Scenario fetched from : %s', scenario_file_name)
- test_file_name = os.path.join(self.TEMP_DIR, test_yaml_file_name)
+ test_file_name = os.path.join(self.temp_dir, test_yaml_file_name)
- if not os.path.exists(self.TEMP_DIR):
- os.makedirs(self.TEMP_DIR)
+ if not os.path.exists(self.temp_dir):
+ os.makedirs(self.temp_dir)
self.apply_blacklist(scenario_file_name, test_file_name)
return test_file_name
@staticmethod
+ def get_verifier_deployment_id():
+ """
+ Returns deployment id for active Rally deployment
+ """
+ cmd = ("rally deployment list | awk '/" +
+ getattr(config.CONF, 'rally_deployment_name') +
+ "/ {print $2}'")
+ with subprocess.Popen(
+ cmd, shell=True, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT) as proc:
+ deployment_uuid = proc.stdout.readline().rstrip()
+ return deployment_uuid.decode("utf-8")
+
+ @staticmethod
+ def create_rally_deployment(environ=None):
+ # pylint: disable=unexpected-keyword-arg
+ """Create new rally deployment"""
+ # set the architecture to default
+ pod_arch = env.get("POD_ARCH")
+ arch_filter = ['aarch64']
+
+ if pod_arch and pod_arch in arch_filter:
+ LOGGER.info("Apply aarch64 specific to rally config...")
+ with open(
+ RallyBase.rally_aar4_patch_path, "r",
+ encoding='utf-8') as pfile:
+ rally_patch_conf = pfile.read()
+
+ for line in fileinput.input(RallyBase.rally_conf_path):
+ print(line, end=' ')
+ if "cirros|testvm" in line:
+ print(rally_patch_conf)
+
+ LOGGER.info("Creating Rally environment...")
+ try:
+ cmd = ['rally', 'deployment', 'destroy',
+ '--deployment',
+ str(getattr(config.CONF, 'rally_deployment_name'))]
+ output = subprocess.check_output(cmd)
+ LOGGER.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
+ except subprocess.CalledProcessError:
+ pass
+
+ cmd = ['rally', 'deployment', 'create', '--fromenv',
+ '--name', str(getattr(config.CONF, 'rally_deployment_name'))]
+ output = subprocess.check_output(cmd, env=environ)
+ LOGGER.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
+
+ cmd = ['rally', 'deployment', 'check']
+ output = subprocess.check_output(cmd)
+ LOGGER.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
+ return RallyBase.get_verifier_deployment_id()
+
+ @staticmethod
def update_keystone_default_role(rally_conf='/etc/rally/rally.conf'):
"""Set keystone_default_role in rally.conf"""
if env.get("NEW_USER_ROLE").lower() != "member":
@@ -156,7 +230,7 @@ class RallyBase(singlevm.VmReady2):
rconfig.add_section('openstack')
rconfig.set(
'openstack', 'keystone_default_role', env.get("NEW_USER_ROLE"))
- with open(rally_conf, 'wb') as config_file:
+ with open(rally_conf, 'w', encoding='utf-8') as config_file:
rconfig.write(config_file)
@staticmethod
@@ -167,24 +241,21 @@ class RallyBase(singlevm.VmReady2):
rconfig.read(rally_conf)
if rconfig.has_option('openstack', 'keystone_default_role'):
rconfig.remove_option('openstack', 'keystone_default_role')
- with open(rally_conf, 'wb') as config_file:
+ with open(rally_conf, 'w', encoding='utf-8') as config_file:
rconfig.write(config_file)
@staticmethod
- def get_task_id(cmd_raw):
+ def get_task_id(tag):
"""
Get task id from command rally result.
- :param cmd_raw:
+ :param tag:
:return: task_id as string
"""
- taskid_re = re.compile('^Task +(.*): started$')
- for line in cmd_raw.splitlines(True):
- line = line.strip()
- match = taskid_re.match(line)
- if match:
- return match.group(1)
- return None
+ cmd = ["rally", "task", "list", "--tag", tag, "--uuids-only"]
+ output = subprocess.check_output(cmd).decode("utf-8").rstrip()
+ LOGGER.info("%s: %s", " ".join(cmd), output)
+ return output
@staticmethod
def task_succeed(json_raw):
@@ -222,7 +293,9 @@ class RallyBase(singlevm.VmReady2):
"""Exclude scenario."""
black_tests = []
try:
- with open(RallyBase.BLACKLIST_FILE, 'r') as black_list_file:
+ with open(
+ RallyBase.blacklist_file, 'r',
+ encoding='utf-8') as black_list_file:
black_list_yaml = yaml.safe_load(black_list_file)
deploy_scenario = env.get('DEPLOY_SCENARIO')
@@ -266,13 +339,19 @@ class RallyBase(singlevm.VmReady2):
func_list = []
try:
- with open(RallyBase.BLACKLIST_FILE, 'r') as black_list_file:
+ with open(
+ RallyBase.blacklist_file, 'r',
+ encoding='utf-8') as black_list_file:
black_list_yaml = yaml.safe_load(black_list_file)
+ if env.get('BLOCK_MIGRATION').lower() == 'true':
+ func_list.append("block_migration")
if not self._migration_supported():
func_list.append("no_migration")
if not self._network_trunk_supported():
func_list.append("no_net_trunk_service")
+ if not self.ext_net:
+ func_list.append("no_floating_ip")
if 'functionality' in black_list_yaml.keys():
for item in black_list_yaml['functionality']:
@@ -289,31 +368,25 @@ class RallyBase(singlevm.VmReady2):
def apply_blacklist(self, case_file_name, result_file_name):
"""Apply blacklist."""
LOGGER.debug("Applying blacklist...")
- cases_file = open(case_file_name, 'r')
- result_file = open(result_file_name, 'w')
-
- black_tests = list(set(self.excl_func() +
- self.excl_scenario()))
-
- if black_tests:
- LOGGER.debug("Blacklisted tests: %s", str(black_tests))
-
- include = True
- for cases_line in cases_file:
- if include:
- for black_tests_line in black_tests:
- if re.search(black_tests_line,
- cases_line.strip().rstrip(':')):
- include = False
- break
+ with open(case_file_name, 'r', encoding='utf-8') as cases_file, open(
+ result_file_name, 'w', encoding='utf-8') as result_file:
+ black_tests = list(set(self.excl_func() + self.excl_scenario()))
+ if black_tests:
+ LOGGER.debug("Blacklisted tests: %s", str(black_tests))
+
+ include = True
+ for cases_line in cases_file:
+ if include:
+ for black_tests_line in black_tests:
+ if re.search(black_tests_line,
+ cases_line.strip().rstrip(':')):
+ include = False
+ break
+ else:
+ result_file.write(str(cases_line))
else:
- result_file.write(str(cases_line))
- else:
- if cases_line.isspace():
- include = True
-
- cases_file.close()
- result_file.close()
+ if cases_line.isspace():
+ include = True
@staticmethod
def file_is_empty(file_name):
@@ -338,27 +411,19 @@ class RallyBase(singlevm.VmReady2):
cmd = (["rally", "task", "detailed", "--uuid", task_id])
LOGGER.debug('running command: %s', cmd)
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- LOGGER.info("%s\n%s", " ".join(cmd), output)
+ LOGGER.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
# save report as JSON
- report_json_name = '{}.json'.format(test_name)
+ report_json_name = f'{test_name}.json'
report_json_dir = os.path.join(self.results_dir, report_json_name)
cmd = (["rally", "task", "report", "--json", "--uuid", task_id,
"--out", report_json_dir])
LOGGER.debug('running command: %s', cmd)
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- LOGGER.info("%s\n%s", " ".join(cmd), output)
+ LOGGER.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
- # save report as HTML
- report_html_name = '{}.html'.format(test_name)
- report_html_dir = os.path.join(self.results_dir, report_html_name)
- cmd = (["rally", "task", "report", "--html", "--uuid", task_id,
- "--out", report_html_dir])
- LOGGER.debug('running command: %s', cmd)
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- LOGGER.info("%s\n%s", " ".join(cmd), output)
-
- json_results = open(report_json_dir).read()
+ with open(report_json_dir, encoding='utf-8') as json_file:
+ json_results = json_file.read()
self._append_summary(json_results, test_name)
# parse JSON operation result
@@ -371,27 +436,33 @@ class RallyBase(singlevm.VmReady2):
"""Run a task."""
LOGGER.info('Starting test scenario "%s" ...', test_name)
LOGGER.debug('running command: %s', self.run_cmd)
- proc = subprocess.Popen(self.run_cmd, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- output = proc.communicate()[0]
-
- task_id = self.get_task_id(output)
+ if six.PY3:
+ subprocess.call(
+ self.run_cmd, timeout=self.task_timeout,
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
+ else:
+ with open(os.devnull, 'wb') as devnull:
+ subprocess.call(self.run_cmd, stdout=devnull, stderr=devnull)
+ task_id = self.get_task_id(test_name)
LOGGER.debug('task_id : %s', task_id)
- if task_id is None:
+ if not task_id:
LOGGER.error("Failed to retrieve task_id")
- LOGGER.error("Result:\n%s", output)
raise Exception("Failed to retrieve task id")
self._save_results(test_name, task_id)
def _append_summary(self, json_raw, test_name):
+ # pylint: disable=too-many-locals
"""Update statistics summary info."""
nb_tests = 0
nb_success = 0
overall_duration = 0.0
+ success = []
+ failures = []
rally_report = json.loads(json_raw)
for task in rally_report.get('tasks'):
for subtask in task.get('subtasks'):
+ has_errors = False
for workload in subtask.get('workloads'):
if workload.get('full_duration'):
overall_duration += workload.get('full_duration')
@@ -402,50 +473,59 @@ class RallyBase(singlevm.VmReady2):
for result in workload.get('data'):
if not result.get('error'):
nb_success += 1
+ else:
+ has_errors = True
+
+ if has_errors:
+ failures.append(subtask['title'])
+ else:
+ success.append(subtask['title'])
scenario_summary = {'test_name': test_name,
'overall_duration': overall_duration,
'nb_tests': nb_tests,
'nb_success': nb_success,
+ 'success': success,
+ 'failures': failures,
'task_status': self.task_succeed(json_raw)}
self.summary.append(scenario_summary)
- def prepare_run(self):
+ def prepare_run(self, **kwargs):
"""Prepare resources needed by test scenarios."""
assert self.cloud
- LOGGER.debug('Validating the test name...')
- if self.test_name == 'all':
- self.tests = self.TESTS
- elif self.test_name in self.TESTS:
- self.tests = [self.test_name]
- else:
- raise Exception("Test name '%s' is invalid" % self.test_name)
+ LOGGER.debug('Validating run tests...')
+ for test in kwargs.get('tests', self.stests):
+ if test in self.stests:
+ self.tests.append(test)
+ else:
+ raise Exception(f"Test name '{test}' is invalid")
- if not os.path.exists(self.TASK_DIR):
- os.makedirs(self.TASK_DIR)
+ if not os.path.exists(self.task_dir):
+ os.makedirs(self.task_dir)
- task = os.path.join(self.RALLY_DIR, 'task.yaml')
+ task = os.path.join(self.rally_dir, 'task.yaml')
if not os.path.exists(task):
LOGGER.error("Task file '%s' does not exist.", task)
- raise Exception("Task file '{}' does not exist.".
- format(task))
- self.task_file = os.path.join(self.TASK_DIR, 'task.yaml')
+ raise Exception(f"Task file '{task}' does not exist.")
+ self.task_file = os.path.join(self.task_dir, 'task.yaml')
shutil.copyfile(task, self.task_file)
- task_macro = os.path.join(self.RALLY_DIR, 'macro')
+ task_macro = os.path.join(self.rally_dir, 'macro')
if not os.path.exists(task_macro):
LOGGER.error("Task macro dir '%s' does not exist.", task_macro)
- raise Exception("Task macro dir '{}' does not exist.".
- format(task_macro))
- macro_dir = os.path.join(self.TASK_DIR, 'macro')
+ raise Exception(f"Task macro dir '{task_macro}' does not exist.")
+ macro_dir = os.path.join(self.task_dir, 'macro')
if os.path.exists(macro_dir):
shutil.rmtree(macro_dir)
shutil.copytree(task_macro, macro_dir)
self.update_keystone_default_role()
- self.compute_cnt = len(self.cloud.list_hypervisors())
+ self.compute_cnt = self.count_hypervisors()
self.network_extensions = self.cloud.get_network_extensions()
self.flavor_alt = self.create_flavor_alt()
+ self.services = [service.name for service in
+ functest_utils.list_services(self.cloud)]
+
LOGGER.debug("flavor: %s", self.flavor_alt)
def prepare_task(self, test_name):
@@ -454,16 +534,19 @@ class RallyBase(singlevm.VmReady2):
if self.file_is_empty(file_name):
LOGGER.info('No tests for scenario "%s"', test_name)
return False
- self.run_cmd = (["rally", "task", "start", "--abort-on-sla-failure",
+ self.run_cmd = (["rally", "task", "start", "--tag", test_name,
+ "--abort-on-sla-failure",
"--task", self.task_file, "--task-args",
- str(self._build_task_args(test_name))])
+ str(self.build_task_args(test_name))])
return True
- def run_tests(self):
+ def run_tests(self, **kwargs):
"""Execute tests."""
+ optional = kwargs.get('optional', [])
for test in self.tests:
- if self.prepare_task(test):
- self.run_task(test)
+ if test in self.services or test not in optional:
+ if self.prepare_task(test):
+ self.run_task(test)
def _generate_report(self):
"""Generate test execution summary report."""
@@ -491,7 +574,7 @@ class RallyBase(singlevm.VmReady2):
success_avg = 100 * item['nb_success'] / item['nb_tests']
except ZeroDivisionError:
success_avg = 0
- success_str = str("{:0.2f}".format(success_avg)) + '%'
+ success_str = f"{success_avg:0.2f}%"
duration_str = time.strftime("%H:%M:%S",
time.gmtime(item['overall_duration']))
res_table.add_row([item['test_name'], duration_str,
@@ -499,7 +582,9 @@ class RallyBase(singlevm.VmReady2):
payload.append({'module': item['test_name'],
'details': {'duration': item['overall_duration'],
'nb tests': item['nb_tests'],
- 'success': success_str}})
+ 'success rate': success_str,
+ 'success': item['success'],
+ 'failures': item['failures']}})
total_duration_str = time.strftime("%H:%M:%S",
time.gmtime(total_duration))
@@ -507,7 +592,7 @@ class RallyBase(singlevm.VmReady2):
self.result = 100 * total_nb_success / total_nb_tests
except ZeroDivisionError:
self.result = 100
- success_rate = "{:0.2f}".format(self.result)
+ success_rate = f"{self.result:0.2f}"
success_rate_str = str(success_rate) + '%'
res_table.add_row(["", "", "", ""])
res_table.add_row(["TOTAL:", total_duration_str, total_nb_tests,
@@ -517,17 +602,52 @@ class RallyBase(singlevm.VmReady2):
LOGGER.info("Rally '%s' success_rate is %s%% in %s/%s modules",
self.case_name, success_rate, nb_modules,
len(self.summary))
- payload.append({'summary': {'duration': total_duration,
- 'nb tests': total_nb_tests,
- 'nb success': success_rate}})
- self.details = payload
+ self.details['summary'] = {'duration': total_duration,
+ 'nb tests': total_nb_tests,
+ 'nb success': success_rate}
+ self.details["modules"] = payload
+
+ @staticmethod
+ def export_task(file_name, export_type="html"):
+ """Export all task results (e.g. html or xunit report)
+
+ Raises:
+ subprocess.CalledProcessError: if Rally doesn't return 0
+
+ Returns:
+ None
+ """
+ cmd = ["rally", "task", "export", "--type", export_type,
+ "--deployment",
+ str(getattr(config.CONF, 'rally_deployment_name')),
+ "--to", file_name]
+ LOGGER.debug('running command: %s', cmd)
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ LOGGER.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
+
+ @staticmethod
+ def verify_report(file_name, uuid, export_type="html"):
+ """Generate the verifier report (e.g. html or xunit report)
+
+ Raises:
+ subprocess.CalledProcessError: if Rally doesn't return 0
+
+ Returns:
+ None
+ """
+ cmd = ["rally", "verify", "report", "--type", export_type,
+ "--uuid", uuid, "--to", file_name]
+ LOGGER.debug('running command: %s', cmd)
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ LOGGER.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
def clean(self):
"""Cleanup of OpenStack resources. Should be called on completion."""
self.clean_rally_conf()
+ self.clean_rally_logs()
if self.flavor_alt:
self.orig_cloud.delete_flavor(self.flavor_alt.id)
- super(RallyBase, self).clean()
+ super().clean()
def is_successful(self):
"""The overall result of the test."""
@@ -535,33 +655,57 @@ class RallyBase(singlevm.VmReady2):
if item['task_status'] is False:
return testcase.TestCase.EX_TESTCASE_FAILED
- return super(RallyBase, self).is_successful()
+ return super().is_successful()
+
+ @staticmethod
+ def update_rally_logs(res_dir, rally_conf='/etc/rally/rally.conf'):
+ """Print rally logs in res dir"""
+ if not os.path.exists(res_dir):
+ os.makedirs(res_dir)
+ rconfig = configparser.RawConfigParser()
+ rconfig.read(rally_conf)
+ rconfig.set('DEFAULT', 'debug', True)
+ rconfig.set('DEFAULT', 'use_stderr', False)
+ rconfig.set('DEFAULT', 'log-file', 'rally.log')
+ rconfig.set('DEFAULT', 'log_dir', res_dir)
+ with open(rally_conf, 'w', encoding='utf-8') as config_file:
+ rconfig.write(config_file)
+
+ @staticmethod
+ def clean_rally_logs(rally_conf='/etc/rally/rally.conf'):
+ """Clean Rally config"""
+ rconfig = configparser.RawConfigParser()
+ rconfig.read(rally_conf)
+ if rconfig.has_option('DEFAULT', 'use_stderr'):
+ rconfig.remove_option('DEFAULT', 'use_stderr')
+ if rconfig.has_option('DEFAULT', 'debug'):
+ rconfig.remove_option('DEFAULT', 'debug')
+ if rconfig.has_option('DEFAULT', 'log-file'):
+ rconfig.remove_option('DEFAULT', 'log-file')
+ if rconfig.has_option('DEFAULT', 'log_dir'):
+ rconfig.remove_option('DEFAULT', 'log_dir')
+ with open(rally_conf, 'w', encoding='utf-8') as config_file:
+ rconfig.write(config_file)
- @energy.enable_recording
def run(self, **kwargs):
"""Run testcase."""
self.start_time = time.time()
try:
- assert super(RallyBase, self).run(
+ assert super().run(
**kwargs) == testcase.TestCase.EX_OK
- environ = dict(
- os.environ,
- OS_USERNAME=self.project.user.name,
- OS_PROJECT_NAME=self.project.project.name,
- OS_PROJECT_ID=self.project.project.id,
- OS_PASSWORD=self.project.password)
- try:
- del environ['OS_TENANT_NAME']
- del environ['OS_TENANT_ID']
- except Exception: # pylint: disable=broad-except
- pass
- conf_utils.create_rally_deployment(environ=environ)
- self.prepare_run()
- self.run_tests()
+ self.update_rally_logs(self.res_dir)
+ self.create_rally_deployment(environ=self.project.get_environ())
+ self.prepare_run(**kwargs)
+ self.run_tests(**kwargs)
self._generate_report()
+ self.export_task(
+ f"{self.results_dir}/{self.case_name}.html")
+ self.export_task(
+ f"{self.results_dir}/{self.case_name}.xml",
+ export_type="junit-xml")
res = testcase.TestCase.EX_OK
- except Exception as exc: # pylint: disable=broad-except
- LOGGER.error('Error with run: %s', exc)
+ except Exception: # pylint: disable=broad-except
+ LOGGER.exception('Error with run:')
self.result = 0
res = testcase.TestCase.EX_RUN_ERROR
self.stop_time = time.time()
@@ -575,49 +719,50 @@ class RallySanity(RallyBase):
"""Initialize RallySanity object."""
if "case_name" not in kwargs:
kwargs["case_name"] = "rally_sanity"
- super(RallySanity, self).__init__(**kwargs)
- self.test_name = 'all'
+ super().__init__(**kwargs)
self.smoke = True
- self.scenario_dir = os.path.join(self.RALLY_SCENARIO_DIR, 'sanity')
+ self.scenario_dir = os.path.join(self.rally_scenario_dir, 'sanity')
class RallyFull(RallyBase):
"""Rally full testcase implementation."""
+ task_timeout = 7200
+
def __init__(self, **kwargs):
"""Initialize RallyFull object."""
if "case_name" not in kwargs:
kwargs["case_name"] = "rally_full"
- super(RallyFull, self).__init__(**kwargs)
- self.test_name = 'all'
+ super().__init__(**kwargs)
self.smoke = False
- self.scenario_dir = os.path.join(self.RALLY_SCENARIO_DIR, 'full')
+ self.scenario_dir = os.path.join(self.rally_scenario_dir, 'full')
class RallyJobs(RallyBase):
"""Rally OpenStack CI testcase implementation."""
- TESTS = ["neutron"]
+ stests = ["neutron"]
+ task_timeout = 7200
def __init__(self, **kwargs):
"""Initialize RallyJobs object."""
if "case_name" not in kwargs:
kwargs["case_name"] = "rally_jobs"
- super(RallyJobs, self).__init__(**kwargs)
- self.test_name = 'all'
- self.task_file = os.path.join(self.RALLY_DIR, 'rally_jobs.yaml')
+ super().__init__(**kwargs)
+ self.task_file = os.path.join(self.rally_dir, 'rally_jobs.yaml')
self.task_yaml = None
- def prepare_run(self):
+ def prepare_run(self, **kwargs):
"""Create resources needed by test scenarios."""
- super(RallyJobs, self).prepare_run()
- with open(os.path.join(self.RALLY_DIR,
- 'rally_jobs.yaml'), 'r') as task_file:
+ super().prepare_run(**kwargs)
+ with open(
+ os.path.join(self.rally_dir, 'rally_jobs.yaml'),
+ 'r', encoding='utf-8') as task_file:
self.task_yaml = yaml.safe_load(task_file)
- if not all(task in self.task_yaml for task in self.tests):
- raise Exception("Test '%s' not in '%s'" %
- (self.test_name, self.tests))
+ for task in self.task_yaml:
+ if task not in self.tests:
+ raise Exception(f"Test '{task}' not in '{self.tests}'")
def apply_blacklist(self, case_file_name, result_file_name):
# pylint: disable=too-many-branches
@@ -629,7 +774,7 @@ class RallyJobs(RallyBase):
LOGGER.debug("Blacklisted tests: %s", str(black_tests))
template = YAML(typ='jinja2')
- with open(case_file_name, 'r') as fname:
+ with open(case_file_name, 'r', encoding='utf-8') as fname:
cases = template.load(fname)
if cases.get("version", 1) == 1:
# scenarios in dictionary
@@ -638,63 +783,56 @@ class RallyJobs(RallyBase):
cases.pop(name)
else:
# workloads in subtasks
- for sind, subtask in enumerate(cases.get('subtasks', [])):
- idx = []
- for wind, workload in enumerate(subtask.get('workloads', [])):
+ for sind, subtask in reversed(list(
+ enumerate(cases.get('subtasks', [])))):
+ for wind, workload in reversed(list(
+ enumerate(subtask.get('workloads', [])))):
scenario = workload.get('scenario', {})
for name in scenario.keys():
if self.in_iterable_re(name, black_tests):
- idx.append(wind)
+ cases['subtasks'][sind]['workloads'].pop(wind)
break
- for wind in reversed(idx):
- cases['subtasks'][sind]['workloads'].pop(wind)
+ if 'workloads' in cases['subtasks'][sind]:
+ if not cases['subtasks'][sind]['workloads']:
+ cases['subtasks'].pop(sind)
# scenarios in subtasks
- idx = []
- for sind, subtask in enumerate(cases.get('subtasks', [])):
+ for sind, subtask in reversed(list(
+ enumerate(cases.get('subtasks', [])))):
scenario = subtask.get('scenario', {})
for name in scenario.keys():
if self.in_iterable_re(name, black_tests):
- idx.append(sind)
+ cases['subtasks'].pop(sind)
break
- for sind in reversed(idx):
- cases['subtasks'].pop(sind)
- with open(result_file_name, 'w') as fname:
+ with open(result_file_name, 'w', encoding='utf-8') as fname:
template.dump(cases, fname)
- @staticmethod
- def _remove_plugins_extra():
- inst_dir = getattr(config.CONF, 'dir_rally_inst')
- try:
- shutil.rmtree(os.path.join(inst_dir, 'plugins'))
- shutil.rmtree(os.path.join(inst_dir, 'extra'))
- except Exception: # pylint: disable=broad-except
- pass
+ def build_task_args(self, test_name):
+ """Build arguments for the Rally task."""
+ task_args = {}
+ if self.ext_net:
+ task_args['floating_network'] = str(self.ext_net.name)
+ else:
+ task_args['floating_network'] = ''
+ task_args['image_name'] = str(self.image.name)
+ task_args['flavor_name'] = str(self.flavor.name)
+ return task_args
def prepare_task(self, test_name):
"""Prepare resources for test run."""
- self._remove_plugins_extra()
jobs_dir = os.path.join(
getattr(config.CONF, 'dir_rally_data'), test_name, 'rally-jobs')
- inst_dir = getattr(config.CONF, 'dir_rally_inst')
- shutil.copytree(os.path.join(jobs_dir, 'plugins'),
- os.path.join(inst_dir, 'plugins'))
- shutil.copytree(os.path.join(jobs_dir, 'extra'),
- os.path.join(inst_dir, 'extra'))
-
task_name = self.task_yaml.get(test_name).get("task")
task = os.path.join(jobs_dir, task_name)
if not os.path.exists(task):
- raise Exception("The scenario '%s' does not exist." % task)
+ raise Exception(f"The scenario '{task}' does not exist.")
LOGGER.debug('Scenario fetched from : %s', task)
- if not os.path.exists(self.TEMP_DIR):
- os.makedirs(self.TEMP_DIR)
- task_file_name = os.path.join(self.TEMP_DIR, task_name)
+ if not os.path.exists(self.temp_dir):
+ os.makedirs(self.temp_dir)
+ task_file_name = os.path.join(self.temp_dir, task_name)
self.apply_blacklist(task, task_file_name)
- self.run_cmd = (["rally", "task", "start", "--task", task_file_name])
+ self.run_cmd = (["rally", "task", "start", "--tag", test_name,
+ "--task", task_file_name,
+ "--task-args", str(self.build_task_args(test_name))])
return True
-
- def clean(self):
- self._remove_plugins_extra()
- super(RallyJobs, self).clean()
diff --git a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-cinder.yaml b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-cinder.yaml
index f36d0b2d9..7abeeac68 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-cinder.yaml
+++ b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-cinder.yaml
@@ -8,6 +8,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -23,6 +25,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{{ volumes() }}
{% endcall %}
runner:
@@ -39,6 +43,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -52,6 +58,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -70,6 +78,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -91,6 +101,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -103,7 +115,7 @@
{{ vm_params(image_name,flavor_name) }}
size:
min: 1
- max: 5
+ max: 1
create_vm_params:
nics:
- net-id: {{ netid }}
@@ -111,6 +123,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -123,17 +137,21 @@
size: 1
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
-
args:
size:
min: 1
- max: 5
+ max: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -148,6 +166,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
volumes:
size: 1
volumes_per_tenant: 4
@@ -165,6 +185,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{{ volumes() }}
{% endcall %}
runner:
@@ -182,6 +204,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -194,6 +218,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -206,6 +232,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -221,6 +249,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -235,6 +265,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{{ volumes() }}
{% endcall %}
runner:
@@ -250,6 +282,8 @@
read_iops_sec: "1000"
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -263,6 +297,8 @@
read_iops_sec: "1000"
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -279,6 +315,8 @@
set_read_iops_sec: "1001"
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -290,6 +328,8 @@
description: "rally tests creating types"
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -301,18 +341,8 @@
description: "rally tests creating types"
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
- runner:
- {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
- sla:
- {{ no_failures_sla() }}
-
- CinderVolumeTypes.create_and_update_volume_type:
- -
- args:
- description: "test"
- update_description: "test update"
- context:
- {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -328,17 +358,8 @@
control_location: "front-end"
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
- runner:
- {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
- sla:
- {{ no_failures_sla() }}
-
- CinderVolumeTypes.create_volume_type_add_and_list_type_access:
- -
- args:
- description: "rally tests creating types"
- context:
- {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
diff --git a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-glance.yaml b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-glance.yaml
index dfc1fc156..993b83ff7 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-glance.yaml
+++ b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-glance.yaml
@@ -36,8 +36,9 @@
flavor:
name: {{ flavor_name }}
number_instances: 2
- nics:
- - net-id: {{ netid }}
+ boot_server_kwargs:
+ nics:
+ - net-id: {{ netid }}
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
quotas:
diff --git a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-neutron.yaml b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-neutron.yaml
index 2951e953a..b2248d499 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-neutron.yaml
+++ b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-neutron.yaml
@@ -27,7 +27,8 @@
ports_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
+ network:
+ router: {}
quotas:
neutron:
network: -1
@@ -50,7 +51,6 @@
subnets_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
quotas:
neutron:
network: -1
@@ -74,7 +74,6 @@
subnets_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
quotas:
neutron:
network: -1
@@ -108,7 +107,8 @@
ports_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
+ network:
+ router: {}
quotas:
neutron:
network: -1
@@ -129,7 +129,6 @@
subnets_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
quotas:
neutron:
network: -1
@@ -151,7 +150,6 @@
subnets_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
quotas:
neutron:
network: -1
@@ -185,7 +183,8 @@
ports_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
+ network:
+ router: {}
quotas:
neutron:
network: -1
@@ -206,7 +205,6 @@
subnets_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
quotas:
neutron:
network: -1
@@ -227,7 +225,6 @@
subnets_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
quotas:
neutron:
network: -1
@@ -315,7 +312,8 @@
ports_per_network: 2
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
+ network:
+ router: {}
quotas:
neutron:
network: -1
@@ -332,7 +330,6 @@
subnets_per_network: 2
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
quotas:
neutron:
network: -1
@@ -350,7 +347,8 @@
subnets_per_network: 2
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
+ network:
+ router: {}
quotas:
neutron:
network: -1
diff --git a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml
index 0e65ac15f..210591f9b 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml
+++ b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml
@@ -39,9 +39,6 @@
- net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network:
- networks_per_tenant: 1
- start_cidr: "100.1.0.0/25"
quotas:
{{ unlimited_neutron() }}
{{ unlimited_nova() }}
@@ -59,9 +56,6 @@
- net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network:
- networks_per_tenant: 1
- start_cidr: "100.1.0.0/25"
quotas:
{{ unlimited_neutron() }}
{{ unlimited_nova() }}
@@ -80,9 +74,6 @@
- net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network:
- networks_per_tenant: 1
- start_cidr: "100.1.0.0/25"
quotas:
{{ unlimited_neutron() }}
{{ unlimited_nova() }}
@@ -104,9 +95,6 @@
- net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network:
- networks_per_tenant: 1
- start_cidr: "100.1.0.0/25"
quotas:
{{ unlimited_neutron() }}
{{ unlimited_nova() }}
@@ -124,9 +112,6 @@
- net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network:
- networks_per_tenant: 1
- start_cidr: "100.1.0.0/25"
quotas:
{{ unlimited_neutron() }}
{{ unlimited_nova() }}
@@ -140,11 +125,13 @@
-
args:
{{ vm_params(image_name, flavor_name) }}
- volume_size: 10
+ volume_size: 1
nics:
- net-id: {{ netid }}
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -200,7 +187,7 @@
NovaServers.boot_and_live_migrate_server:
- args:
{{ vm_params(image_name, flavor_name) }}
- block_migration: false
+ block_migration: {{ block_migration }}
nics:
- net-id: {{ netid }}
context:
@@ -214,13 +201,15 @@
-
args:
{{ vm_params(image_name, flavor_name) }}
- size: 10
- block_migration: false
+ size: 1
+ block_migration: {{ block_migration }}
boot_server_kwargs:
nics:
- net-id: {{ netid }}
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -229,13 +218,15 @@
NovaServers.boot_server_from_volume_and_live_migrate:
- args:
{{ vm_params(image_name, flavor_name) }}
- block_migration: false
- volume_size: 10
+ block_migration: {{ block_migration }}
+ volume_size: 1
force_delete: false
nics:
- net-id: {{ netid }}
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -245,14 +236,11 @@
-
args:
{{ vm_params(image_name, flavor_name) }}
- server_kwargs:
+ boot_server_kwargs:
nics:
- net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network:
- networks_per_tenant: 1
- start_cidr: "100.1.0.0/25"
quotas:
{{ unlimited_neutron() }}
{{ unlimited_nova(keypairs=true) }}
@@ -266,18 +254,17 @@
-
args:
{{ vm_params(image_name, flavor_name) }}
- volume_size: 5
+ volume_size: 1
nics:
- net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network:
- networks_per_tenant: 1
- start_cidr: "100.1.0.0/25"
quotas:
{{ unlimited_volumes() }}
{{ unlimited_neutron() }}
{{ unlimited_nova() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -293,9 +280,6 @@
- net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network:
- networks_per_tenant: 1
- start_cidr: "100.1.0.0/25"
quotas:
{{ unlimited_neutron() }}
{{ unlimited_nova() }}
@@ -375,6 +359,8 @@
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
network: {}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -385,8 +371,7 @@
-
args:
{{ vm_params(image_name, flavor_name) }}
- create_floating_ip_args:
- ext_network: {{ floating_network }}
+ floating_network: {{ floating_network }}
nics:
- net-id: {{ netid }}
context:
@@ -402,8 +387,7 @@
-
args:
{{ vm_params(image_name, flavor_name) }}
- create_floating_ip_args:
- ext_network: {{ floating_network }}
+ floating_network: {{ floating_network }}
nics:
- net-id: {{ netid }}
context:
diff --git a/functest/opnfv_tests/openstack/rally/scenario/opnfv-barbican.yaml b/functest/opnfv_tests/openstack/rally/scenario/opnfv-barbican.yaml
new file mode 100644
index 000000000..9dd9ca271
--- /dev/null
+++ b/functest/opnfv_tests/openstack/rally/scenario/opnfv-barbican.yaml
@@ -0,0 +1,98 @@
+ BarbicanContainers.create_and_add:
+ -
+ runner:
+ {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ sla:
+ {{ no_failures_sla() }}
+
+ BarbicanContainers.create_certificate_and_delete:
+ -
+ runner:
+ {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ sla:
+ {{ no_failures_sla() }}
+
+ BarbicanContainers.create_and_delete:
+ -
+ runner:
+ {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ sla:
+ {{ no_failures_sla() }}
+
+ BarbicanContainers.create_rsa_and_delete:
+ -
+ runner:
+ {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ sla:
+ {{ no_failures_sla() }}
+
+ BarbicanSecrets.create_and_delete:
+ -
+ runner:
+ {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ sla:
+ {{ no_failures_sla() }}
+
+ BarbicanSecrets.create_and_get:
+ -
+ runner:
+ {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ sla:
+ {{ no_failures_sla() }}
+
+ BarbicanSecrets.create_and_list:
+ -
+ runner:
+ {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ sla:
+ {{ no_failures_sla() }}
+
+ BarbicanSecrets.create:
+ -
+ runner:
+ {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ sla:
+ {{ no_failures_sla() }}
+
+ BarbicanSecrets.get:
+ -
+ runner:
+ {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ sla:
+ {{ no_failures_sla() }}
+
+ BarbicanContainers.list:
+ -
+ runner:
+ {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ sla:
+ {{ no_failures_sla() }}
+
+ BarbicanSecrets.list:
+ -
+ runner:
+ {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ sla:
+ {{ no_failures_sla() }}
diff --git a/functest/opnfv_tests/openstack/rally/scenario/opnfv-quotas.yaml b/functest/opnfv_tests/openstack/rally/scenario/opnfv-quotas.yaml
index a0682acce..dcb007c50 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/opnfv-quotas.yaml
+++ b/functest/opnfv_tests/openstack/rally/scenario/opnfv-quotas.yaml
@@ -4,6 +4,8 @@
max_quota: 1024
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -15,6 +17,8 @@
max_quota: 1024
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -31,17 +35,6 @@
sla:
{{ no_failures_sla() }}
- Quotas.nova_update_and_delete:
- -
- args:
- max_quota: 1024
- context:
- {{ user_context(tenants_amount, users_amount, use_existing_users) }}
- runner:
- {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
- sla:
- {{ no_failures_sla() }}
-
Quotas.nova_update:
-
args:
diff --git a/functest/opnfv_tests/openstack/rally/scenario/opnfv-swift.yaml b/functest/opnfv_tests/openstack/rally/scenario/opnfv-swift.yaml
new file mode 100644
index 000000000..66d7cd24d
--- /dev/null
+++ b/functest/opnfv_tests/openstack/rally/scenario/opnfv-swift.yaml
@@ -0,0 +1,71 @@
+ SwiftObjects.create_container_and_object_then_list_objects:
+ -
+ args:
+ objects_per_container: 2
+ object_size: 5120
+ runner:
+ {{ constant_runner(concurrency=1, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ roles:
+ - "admin"
+ sla:
+ {{ no_failures_sla() }}
+
+ SwiftObjects.list_objects_in_containers:
+ -
+ runner:
+ {{ constant_runner(concurrency=1, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ roles:
+ - "admin"
+ swift_objects:
+ containers_per_tenant: 1
+ objects_per_container: 10
+ object_size: 1024
+ sla:
+ {{ no_failures_sla() }}
+
+ SwiftObjects.create_container_and_object_then_download_object:
+ -
+ args:
+ objects_per_container: 5
+ object_size: 1024
+ runner:
+ {{ constant_runner(concurrency=1, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ roles:
+ - "admin"
+ sla:
+ {{ no_failures_sla() }}
+
+ SwiftObjects.create_container_and_object_then_delete_all:
+ -
+ args:
+ objects_per_container: 5
+ object_size: 102400
+ runner:
+ {{ constant_runner(concurrency=1, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ roles:
+ - "admin"
+ sla:
+ {{ no_failures_sla() }}
+
+ SwiftObjects.list_and_download_objects_in_containers:
+ -
+ runner:
+ {{ constant_runner(concurrency=1, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ roles:
+ - "admin"
+ swift_objects:
+ containers_per_tenant: 1
+ objects_per_container: 5
+ object_size: 10240
+ sla:
+ {{ no_failures_sla() }}
diff --git a/functest/opnfv_tests/openstack/rally/scenario/opnfv-vm.yaml b/functest/opnfv_tests/openstack/rally/scenario/opnfv-vm.yaml
new file mode 100644
index 000000000..3aa8ac8e5
--- /dev/null
+++ b/functest/opnfv_tests/openstack/rally/scenario/opnfv-vm.yaml
@@ -0,0 +1,19 @@
+ VMTasks.dd_load_test:
+ -
+ args:
+ flavor:
+ name: {{ flavor_name }}
+ image:
+ name: {{ image_name }}
+ nics:
+ - net-id: {{ netid }}
+ floating_network: {{ floating_network }}
+ force_delete: false
+ username: {{ username }}
+ runner:
+ {{ constant_runner(concurrency=1, times=iterations, is_smoke=smoke) }}
+ context:
+ {{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ network: {}
+ sla:
+ {{ no_failures_sla() }}
diff --git a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-cinder.yaml b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-cinder.yaml
index 832358075..f94a5a1a4 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-cinder.yaml
+++ b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-cinder.yaml
@@ -6,6 +6,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{{ volumes() }}
{% endcall %}
runner:
@@ -23,6 +25,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -35,6 +39,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -47,6 +53,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -62,6 +70,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -76,6 +86,8 @@
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
quotas:
{{ unlimited_volumes() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{{ volumes() }}
{% endcall %}
runner:
@@ -91,6 +103,8 @@
read_iops_sec: "1000"
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -107,6 +121,8 @@
set_read_iops_sec: "1001"
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -118,6 +134,8 @@
description: "rally tests creating types"
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -133,6 +151,8 @@
control_location: "front-end"
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
diff --git a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-glance.yaml b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-glance.yaml
index 1b61762f9..279e81439 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-glance.yaml
+++ b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-glance.yaml
@@ -36,8 +36,9 @@
flavor:
name: {{ flavor_name }}
number_instances: 2
- nics:
- - net-id: {{ netid }}
+ boot_server_kwargs:
+ nics:
+ - net-id: {{ netid }}
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
quotas:
diff --git a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-neutron.yaml b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-neutron.yaml
index da99a48b5..3eb7652c0 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-neutron.yaml
+++ b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-neutron.yaml
@@ -21,7 +21,8 @@
ports_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
+ network:
+ router: {}
quotas:
neutron:
network: -1
@@ -42,7 +43,6 @@
subnets_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
quotas:
neutron:
network: -1
@@ -64,7 +64,8 @@
subnets_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
+ network:
+ router: {}
quotas:
neutron:
network: -1
@@ -98,7 +99,8 @@
ports_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
+ network:
+ router: {}
quotas:
neutron:
network: -1
@@ -119,7 +121,6 @@
subnets_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
quotas:
neutron:
network: -1
@@ -140,7 +141,6 @@
subnets_per_network: 1
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network: {}
quotas:
neutron:
network: -1
diff --git a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-nova.yaml b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-nova.yaml
index 7dd252da5..1fbfccb5a 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-nova.yaml
+++ b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-nova.yaml
@@ -1,7 +1,7 @@
NovaServers.boot_and_live_migrate_server:
- args:
{{ vm_params(image_name, flavor_name) }}
- block_migration: false
+ block_migration: {{ block_migration }}
nics:
- net-id: {{ netid }}
context:
@@ -15,13 +15,15 @@
-
args:
{{ vm_params(image_name, flavor_name) }}
- size: 10
- block_migration: false
+ size: 1
+ block_migration: {{ block_migration }}
boot_server_kwargs:
nics:
- net-id: {{ netid }}
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -30,13 +32,15 @@
NovaServers.boot_server_from_volume_and_live_migrate:
- args:
{{ vm_params(image_name, flavor_name) }}
- block_migration: false
- volume_size: 10
+ block_migration: {{ block_migration }}
+ volume_size: 1
force_delete: false
nics:
- net-id: {{ netid }}
context:
{{ user_context(tenants_amount, users_amount, use_existing_users) }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
sla:
@@ -46,14 +50,11 @@
-
args:
{{ vm_params(image_name, flavor_name) }}
- server_kwargs:
+ boot_server_kwargs:
nics:
- net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network:
- networks_per_tenant: 1
- start_cidr: "100.1.0.0/25"
quotas:
{{ unlimited_neutron() }}
{{ unlimited_nova(keypairs=true) }}
@@ -67,18 +68,17 @@
-
args:
{{ vm_params(image_name, flavor_name) }}
- volume_size: 5
+ volume_size: 1
nics:
- net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network:
- networks_per_tenant: 1
- start_cidr: "100.1.0.0/25"
quotas:
{{ unlimited_volumes() }}
{{ unlimited_neutron() }}
{{ unlimited_nova() }}
+ api_versions:
+ {{ volume_service(version=volume_version, service_type=volume_service_type) }}
{% endcall %}
runner:
{{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }}
@@ -94,9 +94,6 @@
- net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
- network:
- networks_per_tenant: 1
- start_cidr: "100.1.0.0/25"
quotas:
{{ unlimited_neutron() }}
{{ unlimited_nova() }}
@@ -122,7 +119,8 @@
-
args:
{{ vm_params(image_name, flavor_name) }}
- auto_assign_nic: true
+ nics:
+ - net-id: {{ netid }}
context:
{% call user_context(tenants_amount, users_amount, use_existing_users) %}
network: {}
@@ -136,8 +134,7 @@
-
args:
{{ vm_params(image_name, flavor_name) }}
- create_floating_ip_args:
- ext_network: {{ floating_network }}
+ floating_network: {{ floating_network }}
nics:
- net-id: {{ netid }}
context:
diff --git a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
index 35b107838..75afb2dbe 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
+++ b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
@@ -7,7 +7,7 @@ parameters:
default: public
image:
type: string
- default: cirros-0.4.0-x86_64-uec
+ default: cirros-0.6.1-x86_64-uec
flavor:
type: string
default: m1.tiny
diff --git a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
index 5c9a86b79..9a0f1aa72 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
+++ b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
@@ -4,7 +4,7 @@ parameters:
# set all correct defaults for parameters before launch test
image:
type: string
- default: cirros-0.4.0-x86_64-uec
+ default: cirros-0.5.1-x86_64-uec
flavor:
type: string
default: m1.tiny
diff --git a/functest/opnfv_tests/openstack/rally/task.yaml b/functest/opnfv_tests/openstack/rally/task.yaml
index 14d4e718c..649c04557 100644
--- a/functest/opnfv_tests/openstack/rally/task.yaml
+++ b/functest/opnfv_tests/openstack/rally/task.yaml
@@ -4,7 +4,7 @@
{%- endif %}
{%- from "macro/macro.yaml" import user_context, vm_params, unlimited_volumes, constant_runner, rps_runner, no_failures_sla -%}
-{%- from "macro/macro.yaml" import volumes, unlimited_nova, unlimited_neutron, glance_args -%}
+{%- from "macro/macro.yaml" import volumes, unlimited_nova, unlimited_neutron, glance_args, volume_service -%}
---
{% if "authenticate" in service_list %}
@@ -42,3 +42,15 @@
{% if "heat" in service_list %}
{%- include "var/opnfv-heat.yaml"-%}
{% endif %}
+
+{% if "swift" in service_list %}
+{%- include "var/opnfv-swift.yaml"-%}
+{% endif %}
+
+{% if "barbican" in service_list %}
+{%- include "var/opnfv-barbican.yaml"-%}
+{% endif %}
+
+{% if "vm" in service_list %}
+{%- include "var/opnfv-vm.yaml"-%}
+{% endif %}
diff --git a/functest/opnfv_tests/openstack/refstack/refstack.py b/functest/opnfv_tests/openstack/refstack/refstack.py
index c709e5626..87932020b 100644
--- a/functest/opnfv_tests/openstack/refstack/refstack.py
+++ b/functest/opnfv_tests/openstack/refstack/refstack.py
@@ -24,20 +24,16 @@ class Refstack(tempest.TempestCommon):
__logger = logging.getLogger(__name__)
- defcorelist = os.path.join(
- getattr(config.CONF, 'dir_refstack_data'), 'defcore.txt')
-
- def _extract_refstack_data(self):
+ def _extract_refstack_data(self, refstack_list):
yaml_data = ""
- with open(self.defcorelist) as def_file:
+ with open(refstack_list, encoding='utf-8') as def_file:
for line in def_file:
try:
grp = re.search(r'^([^\[]*)(\[.*\])\n*$', line)
- yaml_data = "{}\n{}: {}".format(
- yaml_data, grp.group(1), grp.group(2))
+ yaml_data = f"{yaml_data}\n{grp.group(1)}: {grp.group(2)}"
except Exception: # pylint: disable=broad-except
self.__logger.warning("Cannot parse %s", line)
- return yaml.load(yaml_data)
+ return yaml.full_load(yaml_data)
def _extract_tempest_data(self):
olddir = os.getcwd()
@@ -48,25 +44,27 @@ class Refstack(tempest.TempestCommon):
except subprocess.CalledProcessError as cpe:
self.__logger.error(
"Exception when listing tempest tests: %s\n%s",
- cpe.cmd, cpe.output)
+ cpe.cmd, cpe.output.decode("utf-8"))
raise
finally:
os.chdir(olddir)
yaml_data2 = ""
for line in output.splitlines():
try:
- grp = re.search(r'^([^\[]*)(\[.*\])\n*$', line)
- yaml_data2 = "{}\n{}: {}".format(
- yaml_data2, grp.group(1), grp.group(2))
+ grp = re.search(r'^([^\[]*)(\[.*\])\n*$', line.decode("utf-8"))
+ yaml_data2 = f"{yaml_data2}\n{grp.group(1)}: {grp.group(2)}"
except Exception: # pylint: disable=broad-except
self.__logger.warning("Cannot parse %s. skipping it", line)
- return yaml.load(yaml_data2)
+ return yaml.full_load(yaml_data2)
def generate_test_list(self, **kwargs):
+ refstack_list = os.path.join(
+ getattr(config.CONF, 'dir_refstack_data'),
+ f"{kwargs.get('target', 'compute')}.txt")
self.backup_tempest_config(self.conf_file, '/etc')
- refstack_data = self._extract_refstack_data()
+ refstack_data = self._extract_refstack_data(refstack_list)
tempest_data = self._extract_tempest_data()
- with open(self.list, 'w') as ref_file:
+ with open(self.list, 'w', encoding='utf-8') as ref_file:
for key in refstack_data.keys():
try:
for data in tempest_data[key]:
@@ -75,9 +73,9 @@ class Refstack(tempest.TempestCommon):
else:
self.__logger.info("%s: ids differ. skipping it", key)
continue
- ref_file.write("{}{}\n".format(
- key, str(tempest_data[key]).replace(
- "'", "").replace(", ", ",")))
+ value = str(tempest_data[key]).replace(
+ "'", "").replace(", ", ",")
+ ref_file.write(f"{key}{value}\n")
except Exception: # pylint: disable=broad-except
self.__logger.info("%s: not found. skipping it", key)
continue
diff --git a/functest/opnfv_tests/openstack/shaker/shaker.py b/functest/opnfv_tests/openstack/shaker/shaker.py
index 1170fede3..275cc3077 100644
--- a/functest/opnfv_tests/openstack/shaker/shaker.py
+++ b/functest/opnfv_tests/openstack/shaker/shaker.py
@@ -19,9 +19,11 @@ and list of tests to execute.
import logging
import os
+import json
import scp
from functest.core import singlevm
+from functest.utils import env
class Shaker(singlevm.SingleVm2):
@@ -30,22 +32,32 @@ class Shaker(singlevm.SingleVm2):
__logger = logging.getLogger(__name__)
- filename = '/home/opnfv/functest/images/shaker-image.qcow2'
+ filename = '/home/opnfv/functest/images/shaker-image-1.3.4+stretch.qcow2'
flavor_ram = 512
flavor_vcpus = 1
flavor_disk = 3
- username = 'ubuntu'
+ username = 'debian'
port = 9000
ssh_connect_loops = 12
create_server_timeout = 300
+ check_console_loop = 12
shaker_timeout = '3600'
+ quota_instances = -1
+ quota_cores = -1
+ check_console_loop = 12
def __init__(self, **kwargs):
- super(Shaker, self).__init__(**kwargs)
+ super().__init__(**kwargs)
self.role = None
+ def check_requirements(self):
+ if self.count_hypervisors() < 2:
+ self.__logger.warning("Shaker requires at least 2 hypervisors")
+ self.is_skipped = True
+ self.project.clean()
+
def prepare(self):
- super(Shaker, self).prepare()
+ super().prepare()
self.cloud.create_security_group_rule(
self.sec.id, port_range_min=self.port, port_range_max=self.port,
protocol='tcp', direction='ingress')
@@ -75,38 +87,41 @@ class Shaker(singlevm.SingleVm2):
"heat_stack_owner", user=self.project.user.id,
project=self.project.project.id,
domain=self.project.domain.id)
+ self.orig_cloud.set_compute_quotas(
+ self.project.project.name,
+ instances=self.quota_instances,
+ cores=self.quota_cores)
scpc = scp.SCPClient(self.ssh.get_transport())
scpc.put('/home/opnfv/functest/conf/env_file', remote_path='~/')
if os.environ.get('OS_CACERT'):
scpc.put(os.environ.get('OS_CACERT'), remote_path='~/os_cacert')
+ opt = 'export OS_CACERT=~/os_cacert && ' if os.environ.get(
+ 'OS_CACERT') else ''
(_, stdout, stderr) = self.ssh.exec_command(
'source ~/env_file && '
'export OS_INTERFACE=public && '
- 'export OS_AUTH_URL={} && '
- 'export OS_USERNAME={} && '
- 'export OS_PROJECT_NAME={} && '
- 'export OS_PROJECT_ID={} && '
+ f'export OS_AUTH_URL={endpoint} && '
+ f'export OS_USERNAME={self.project.user.name} && '
+ f'export OS_PROJECT_NAME={self.project.project.name} && '
+ f'export OS_PROJECT_ID={self.project.project.id} && '
'unset OS_TENANT_NAME && '
'unset OS_TENANT_ID && '
'unset OS_ENDPOINT_TYPE && '
- 'export OS_PASSWORD={} && '
- '{}'
+ f'export OS_PASSWORD="{self.project.password}" && '
+ f'{opt}'
'env && '
- 'timeout {} shaker --image-name {} --flavor-name {} '
- '--server-endpoint {}:9000 --scenario '
- 'openstack/full_l2,'
+ f'timeout {self.shaker_timeout} shaker --debug '
+ f'--image-name {self.image.name} --flavor-name {self.flavor.name} '
+ f'--server-endpoint {self.fip.floating_ip_address}:9000 '
+ f'--external-net {self.ext_net.id} '
+ f"--dns-nameservers {env.get('NAMESERVER')} "
+ '--scenario openstack/full_l2,'
'openstack/full_l3_east_west,'
'openstack/full_l3_north_south,'
'openstack/perf_l3_north_south '
- '--report report.html --output report.json'.format(
- endpoint, self.project.user.name, self.project.project.name,
- self.project.project.id, self.project.password,
- 'export OS_CACERT=~/os_cacert && ' if os.environ.get(
- 'OS_CACERT') else '',
- self.shaker_timeout, self.image.name, self.flavor.name,
- self.fip.floating_ip_address))
- self.__logger.info("output:\n%s", stdout.read())
- self.__logger.info("error:\n%s", stderr.read())
+ '--report report.html --output report.json')
+ self.__logger.info("output:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.info("error:\n%s", stderr.read().decode("utf-8"))
if not os.path.exists(self.res_dir):
os.makedirs(self.res_dir)
try:
@@ -115,9 +130,18 @@ class Shaker(singlevm.SingleVm2):
except scp.SCPException:
self.__logger.exception("cannot get report files")
return 1
+ with open(
+ os.path.join(self.res_dir, 'report.json'),
+ encoding='utf-8') as json_file:
+ data = json.load(json_file)
+ for value in data["records"].values():
+ if value["status"] != "ok":
+ self.__logger.error(
+ "%s failed\n%s", value["scenario"], value["stderr"])
+ return 1
return stdout.channel.recv_exit_status()
def clean(self):
- super(Shaker, self).clean()
+ super().clean()
if self.role:
self.orig_cloud.delete_role(self.role.id)
diff --git a/functest/opnfv_tests/openstack/snaps/__init__.py b/functest/opnfv_tests/openstack/snaps/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/functest/opnfv_tests/openstack/snaps/__init__.py
+++ /dev/null
diff --git a/functest/opnfv_tests/openstack/snaps/api_check.py b/functest/opnfv_tests/openstack/snaps/api_check.py
deleted file mode 100644
index d4204bff1..000000000
--- a/functest/opnfv_tests/openstack/snaps/api_check.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2017 Cable Television Laboratories, Inc. and others.
-#
-# This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-
-"""api_check test case implementation"""
-
-import unittest
-
-from functest.opnfv_tests.openstack.snaps import snaps_suite_builder
-from functest.opnfv_tests.openstack.snaps.snaps_test_runner import \
- SnapsTestRunner
-
-
-class ApiCheck(SnapsTestRunner):
- """
- This test executes the Python Tests included with the SNAPS libraries
- that exercise many of the OpenStack APIs within Keystone, Glance, Neutron,
- and Nova
- """
- def __init__(self, **kwargs):
- if "case_name" not in kwargs:
- kwargs["case_name"] = "api_check"
- super(ApiCheck, self).__init__(**kwargs)
-
- self.suite = unittest.TestSuite()
-
- def run(self, **kwargs):
- """
- Builds the test suite then calls super.run()
- :param kwargs: the arguments to pass on
- :return:
- """
- snaps_suite_builder.add_openstack_client_tests(
- suite=self.suite,
- os_creds=self.os_creds,
- ext_net_name=self.ext_net_name,
- use_keystone=self.use_keystone)
- snaps_suite_builder.add_openstack_api_tests(
- suite=self.suite,
- os_creds=self.os_creds,
- ext_net_name=self.ext_net_name,
- use_keystone=self.use_keystone,
- image_metadata=self.image_metadata)
- return super(ApiCheck, self).run()
diff --git a/functest/opnfv_tests/openstack/snaps/health_check.py b/functest/opnfv_tests/openstack/snaps/health_check.py
deleted file mode 100644
index 3a9c821d2..000000000
--- a/functest/opnfv_tests/openstack/snaps/health_check.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2017 Cable Television Laboratories, Inc. and others.
-#
-# This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-
-"""snaps_health_check test case implementation"""
-
-import unittest
-
-from snaps.openstack.tests.create_instance_tests import SimpleHealthCheck
-from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
-
-from functest.opnfv_tests.openstack.snaps.snaps_test_runner import (
- SnapsTestRunner)
-
-
-class HealthCheck(SnapsTestRunner):
- """
- This test executes the SNAPS Python Test case SimpleHealthCheck which
- creates a VM with a single port with an IPv4 address that is assigned by
- DHCP. This test then validates the expected IP with the actual
- """
- def __init__(self, **kwargs):
- if "case_name" not in kwargs:
- kwargs["case_name"] = "snaps_images_cirros"
- super(HealthCheck, self).__init__(**kwargs)
-
- self.suite = unittest.TestSuite()
-
- def run(self, **kwargs):
- """
- Builds the test suite then calls super.run()
- :param kwargs: the arguments to pass on
- :return:
- """
- self.suite.addTest(
- OSIntegrationTestCase.parameterize(
- SimpleHealthCheck, os_creds=self.os_creds,
- ext_net_name=self.ext_net_name,
- use_keystone=self.use_keystone,
- flavor_metadata=self.flavor_metadata,
- image_metadata=self.image_metadata,
- netconf_override=self.netconf_override))
- return super(HealthCheck, self).run()
diff --git a/functest/opnfv_tests/openstack/snaps/smoke.py b/functest/opnfv_tests/openstack/snaps/smoke.py
deleted file mode 100644
index bc6781180..000000000
--- a/functest/opnfv_tests/openstack/snaps/smoke.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2017 Cable Television Laboratories, Inc. and others.
-#
-# This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-
-"""snaps_smoke test case implementation"""
-
-import unittest
-
-from functest.opnfv_tests.openstack.snaps import snaps_suite_builder
-from functest.opnfv_tests.openstack.snaps.snaps_test_runner import (
- SnapsTestRunner)
-
-
-class SnapsSmoke(SnapsTestRunner):
- """
- This test executes the Python Tests included with the SNAPS libraries
- that exercise many of the OpenStack APIs within Keystone, Glance, Neutron,
- and Nova
- """
- def __init__(self, **kwargs):
- if "case_name" not in kwargs:
- kwargs["case_name"] = "snaps_smoke"
- super(SnapsSmoke, self).__init__(**kwargs)
-
- self.suite = unittest.TestSuite()
-
- def run(self, **kwargs):
- """
- Builds the test suite then calls super.run()
- :param kwargs: the arguments to pass on
- :return:
- """
- snaps_suite_builder.add_openstack_integration_tests(
- suite=self.suite,
- os_creds=self.os_creds,
- ext_net_name=self.ext_net_name,
- use_keystone=self.use_keystone,
- flavor_metadata=self.flavor_metadata,
- image_metadata=self.image_metadata,
- use_floating_ips=self.use_fip,
- netconf_override=self.netconf_override)
- return super(SnapsSmoke, self).run()
diff --git a/functest/opnfv_tests/openstack/snaps/snaps_suite_builder.py b/functest/opnfv_tests/openstack/snaps/snaps_suite_builder.py
deleted file mode 100644
index 309709276..000000000
--- a/functest/opnfv_tests/openstack/snaps/snaps_suite_builder.py
+++ /dev/null
@@ -1,441 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2017 Cable Television Laboratories, Inc. and others.
-#
-# This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-
-"""
-Snaps test suite including openstack client tests, api tests and
-integration tests.
-add_openstack_client_tests: for connection_check
-add_openstack_api_tests: for api_check
-add_openstack_integration_tests: for snaps_smoke
-"""
-
-import logging
-
-from snaps.openstack.tests.create_flavor_tests import (
- CreateFlavorTests)
-from snaps.openstack.tests.create_image_tests import (
- CreateImageSuccessTests, CreateImageNegativeTests,
- CreateMultiPartImageTests)
-from snaps.openstack.tests.create_instance_tests import (
- CreateInstanceOnComputeHost,
- CreateInstanceSimpleTests, InstanceSecurityGroupTests,
- CreateInstancePortManipulationTests, SimpleHealthCheck,
- CreateInstanceFromThreePartImage, CreateInstanceTwoNetTests,
- CreateInstanceVolumeTests)
-from snaps.openstack.tests.create_keypairs_tests import (
- CreateKeypairsTests, CreateKeypairsCleanupTests)
-from snaps.openstack.tests.create_network_tests import (
- CreateNetworkSuccessTests)
-from snaps.openstack.tests.create_project_tests import (
- CreateProjectSuccessTests, CreateProjectUserTests)
-from snaps.openstack.tests.create_qos_tests import (
- CreateQoSTests)
-from snaps.openstack.tests.create_router_tests import (
- CreateRouterSuccessTests, CreateRouterNegativeTests)
-from snaps.openstack.tests.create_security_group_tests import (
- CreateSecurityGroupTests)
-from snaps.openstack.tests.create_stack_tests import (
- CreateStackSuccessTests, CreateStackNegativeTests,
- CreateStackFlavorTests, CreateStackFloatingIpTests,
- CreateStackKeypairTests, CreateStackVolumeTests,
- CreateStackSecurityGroupTests)
-from snaps.openstack.tests.create_user_tests import (
- CreateUserSuccessTests)
-from snaps.openstack.tests.create_volume_tests import (
- CreateSimpleVolumeSuccessTests,
- CreateVolumeWithTypeTests, CreateVolumeWithImageTests,
- CreateSimpleVolumeFailureTests)
-from snaps.openstack.tests.create_volume_type_tests import (
- CreateSimpleVolumeTypeSuccessTests,
- CreateVolumeTypeComplexTests)
-from snaps.openstack.tests.os_source_file_test import (
- OSComponentTestCase, OSIntegrationTestCase)
-from snaps.openstack.utils.tests.cinder_utils_tests import (
- CinderSmokeTests, CinderUtilsQoSTests, CinderUtilsSimpleVolumeTypeTests,
- CinderUtilsAddEncryptionTests, CinderUtilsVolumeTypeCompleteTests,
- CinderUtilsVolumeTests)
-from snaps.openstack.utils.tests.glance_utils_tests import (
- GlanceSmokeTests, GlanceUtilsTests)
-from snaps.openstack.utils.tests.heat_utils_tests import (
- HeatSmokeTests, HeatUtilsCreateSimpleStackTests,
- HeatUtilsCreateComplexStackTests, HeatUtilsFlavorTests,
- HeatUtilsKeypairTests, HeatUtilsSecurityGroupTests)
-from snaps.openstack.utils.tests.keystone_utils_tests import (
- KeystoneSmokeTests, KeystoneUtilsTests)
-from snaps.openstack.utils.tests.neutron_utils_tests import (
- NeutronSmokeTests, NeutronUtilsNetworkTests, NeutronUtilsSubnetTests,
- NeutronUtilsRouterTests, NeutronUtilsSecurityGroupTests,
- NeutronUtilsFloatingIpTests)
-from snaps.openstack.utils.tests.nova_utils_tests import (
- NovaSmokeTests, NovaUtilsKeypairTests, NovaUtilsFlavorTests,
- NovaUtilsInstanceTests, NovaUtilsInstanceVolumeTests)
-from snaps.provisioning.tests.ansible_utils_tests import (
- AnsibleProvisioningTests)
-
-
-def add_openstack_client_tests(suite, os_creds, ext_net_name,
- use_keystone=True, log_level=logging.INFO):
- """
- Adds tests written to exercise OpenStack client retrieval
-
- :param suite: the unittest.TestSuite object to which to add the tests
- :param os_creds: and instance of OSCreds that holds the credentials
- required by OpenStack
- :param ext_net_name: the name of an external network on the cloud under
- test
- :param use_keystone: when True, tests requiring direct access to Keystone
- are added as these need to be running on a host that
- has access to the cloud's private network
- :param log_level: the logging level
- :return: None as the tests will be adding to the 'suite' parameter object
- """
- # Basic connection tests
- suite.addTest(
- OSComponentTestCase.parameterize(
- GlanceSmokeTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
-
- if use_keystone:
- suite.addTest(
- OSComponentTestCase.parameterize(
- KeystoneSmokeTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level))
-
- suite.addTest(
- OSComponentTestCase.parameterize(
- NeutronSmokeTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
- suite.addTest(
- OSComponentTestCase.parameterize(
- NovaSmokeTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
- suite.addTest(
- OSComponentTestCase.parameterize(
- HeatSmokeTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
- suite.addTest(
- OSComponentTestCase.parameterize(
- CinderSmokeTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
-
-
-def add_openstack_api_tests(suite, os_creds, ext_net_name, use_keystone=True,
- image_metadata=None, log_level=logging.INFO):
- # pylint: disable=too-many-arguments
- """
- Adds tests written to exercise all existing OpenStack APIs
-
- :param suite: the unittest.TestSuite object to which to add the tests
- :param os_creds: Instance of OSCreds that holds the credentials
- required by OpenStack
- :param ext_net_name: the name of an external network on the cloud under
- test
- :param use_keystone: when True, tests requiring direct access to Keystone
- are added as these need to be running on a host that
- has access to the cloud's private network
- :param image_metadata: dict() object containing metadata for creating an
- image with custom config
- (see YAML files in examples/image-metadata)
- :param log_level: the logging level
- :return: None as the tests will be adding to the 'suite' parameter object
- """
- # Tests the OpenStack API calls
- if use_keystone:
- suite.addTest(OSComponentTestCase.parameterize(
- KeystoneUtilsTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- CreateUserSuccessTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- CreateProjectSuccessTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- CreateProjectUserTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level))
-
- suite.addTest(OSComponentTestCase.parameterize(
- GlanceUtilsTests, os_creds=os_creds, ext_net_name=ext_net_name,
- image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- NeutronUtilsNetworkTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- NeutronUtilsSubnetTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- NeutronUtilsRouterTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- NeutronUtilsSecurityGroupTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- NeutronUtilsFloatingIpTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- NovaUtilsKeypairTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- NovaUtilsFlavorTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- NovaUtilsInstanceTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level, image_metadata=image_metadata))
- suite.addTest(OSComponentTestCase.parameterize(
- NovaUtilsInstanceVolumeTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level,
- image_metadata=image_metadata))
- suite.addTest(OSComponentTestCase.parameterize(
- CreateFlavorTests, os_creds=os_creds, ext_net_name=ext_net_name,
- log_level=log_level))
- suite.addTest(OSComponentTestCase.parameterize(
- HeatUtilsCreateSimpleStackTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level,
- image_metadata=image_metadata))
- suite.addTest(OSComponentTestCase.parameterize(
- HeatUtilsCreateComplexStackTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level,
- image_metadata=image_metadata))
- suite.addTest(OSComponentTestCase.parameterize(
- HeatUtilsFlavorTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level,
- image_metadata=image_metadata))
- suite.addTest(OSComponentTestCase.parameterize(
- HeatUtilsKeypairTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level,
- image_metadata=image_metadata))
- suite.addTest(OSComponentTestCase.parameterize(
- HeatUtilsSecurityGroupTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level,
- image_metadata=image_metadata))
- suite.addTest(OSComponentTestCase.parameterize(
- CinderUtilsQoSTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level,
- image_metadata=image_metadata))
- suite.addTest(OSComponentTestCase.parameterize(
- CinderUtilsVolumeTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level,
- image_metadata=image_metadata))
- suite.addTest(OSComponentTestCase.parameterize(
- CinderUtilsSimpleVolumeTypeTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level,
- image_metadata=image_metadata))
- suite.addTest(OSComponentTestCase.parameterize(
- CinderUtilsAddEncryptionTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level,
- image_metadata=image_metadata))
- suite.addTest(OSComponentTestCase.parameterize(
- CinderUtilsVolumeTypeCompleteTests, os_creds=os_creds,
- ext_net_name=ext_net_name, log_level=log_level,
- image_metadata=image_metadata))
-
-
-def add_openstack_integration_tests(suite, os_creds, ext_net_name,
- use_keystone=True, flavor_metadata=None,
- image_metadata=None, use_floating_ips=True,
- netconf_override=None,
- log_level=logging.INFO):
- # pylint: disable=too-many-arguments
- """
- Adds tests written to exercise all long-running OpenStack integration tests
- meaning they will be creating VM instances and potentially performing some
- SSH functions through floatingIPs
-
- :param suite: the unittest.TestSuite object to which to add the tests
- :param os_creds: and instance of OSCreds that holds the credentials
- required by OpenStack
- :param ext_net_name: the name of an external network on the cloud under
- test
- :param use_keystone: when True, tests requiring direct access to Keystone
- are added as these need to be running on a host that
- has access to the cloud's private network
- :param image_metadata: dict() object containing metadata for creating an
- image with custom config
- (see YAML files in examples/image-metadata)
- :param flavor_metadata: dict() object containing the metadata required by
- your flavor based on your configuration:
- (i.e. {'hw:mem_page_size': 'large'})
- :param use_floating_ips: when true, all tests requiring Floating IPs will
- be added to the suite
- :param netconf_override: dict() containing the reconfigured network_type,
- physical_network and segmentation_id
- :param log_level: the logging level
- :return: None as the tests will be adding to the 'suite' parameter object
- """
- # Tests the OpenStack API calls via a creator. If use_keystone, objects
- # will be created with a custom user and project
-
- # Creator Object tests
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateSecurityGroupTests, os_creds=os_creds, ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateImageSuccessTests, os_creds=os_creds, ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateImageNegativeTests, os_creds=os_creds, ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateMultiPartImageTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateKeypairsTests, os_creds=os_creds, ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateKeypairsCleanupTests, os_creds=os_creds,
- ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateNetworkSuccessTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateRouterSuccessTests, os_creds=os_creds, ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateRouterNegativeTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateQoSTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateSimpleVolumeTypeSuccessTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateVolumeTypeComplexTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateSimpleVolumeSuccessTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateSimpleVolumeFailureTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateVolumeWithTypeTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateVolumeWithImageTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
-
- # VM Instances
- suite.addTest(OSIntegrationTestCase.parameterize(
- SimpleHealthCheck, os_creds=os_creds, ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateInstanceTwoNetTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateInstanceSimpleTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- netconf_override=netconf_override, log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateInstancePortManipulationTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- netconf_override=netconf_override, log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- InstanceSecurityGroupTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- netconf_override=netconf_override, log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateInstanceOnComputeHost, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- netconf_override=netconf_override, log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateInstanceFromThreePartImage, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- netconf_override=netconf_override, log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateInstanceVolumeTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- netconf_override=netconf_override, log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateStackSuccessTests, os_creds=os_creds, ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateStackVolumeTests, os_creds=os_creds, ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateStackFlavorTests, os_creds=os_creds, ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateStackKeypairTests, os_creds=os_creds, ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateStackSecurityGroupTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateStackNegativeTests, os_creds=os_creds, ext_net_name=ext_net_name,
- use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
-
- if use_floating_ips:
- suite.addTest(OSIntegrationTestCase.parameterize(
- CreateStackFloatingIpTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
- suite.addTest(OSIntegrationTestCase.parameterize(
- AnsibleProvisioningTests, os_creds=os_creds,
- ext_net_name=ext_net_name, use_keystone=use_keystone,
- flavor_metadata=flavor_metadata, image_metadata=image_metadata,
- log_level=log_level))
diff --git a/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py b/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py
deleted file mode 100644
index c937ed744..000000000
--- a/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2017 Cable Television Laboratories, Inc. and others.
-#
-# This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-
-"""configuration params to run snaps tests"""
-
-import logging
-import uuid
-
-import os_client_config
-import shade
-from xtesting.core import unit
-
-from functest.core import tenantnetwork
-from functest.opnfv_tests.openstack.snaps import snaps_utils
-from functest.utils import config
-from functest.utils import functest_utils
-
-
-class SnapsTestRunner(unit.Suite):
- # pylint: disable=too-many-instance-attributes
- """
- This test executes the SNAPS Python Tests
- """
-
- def __init__(self, **kwargs):
- super(SnapsTestRunner, self).__init__(**kwargs)
- self.logger = logging.getLogger(__name__)
-
- try:
- cloud_config = os_client_config.get_config()
- self.orig_cloud = shade.OpenStackCloud(cloud_config=cloud_config)
- guid = str(uuid.uuid4())
- self.project = tenantnetwork.NewProject(
- self.orig_cloud, self.case_name, guid)
- self.project.create()
- except Exception: # pylint: disable=broad-except
- raise Exception("Cannot create user or project")
-
- if self.orig_cloud.get_role("admin"):
- role_name = "admin"
- elif self.orig_cloud.get_role("Admin"):
- role_name = "Admin"
- else:
- raise Exception("Cannot detect neither admin nor Admin")
- self.orig_cloud.grant_role(
- role_name, user=self.project.user.id,
- project=self.project.project.id,
- domain=self.project.domain.id)
- self.role = None
- if not self.orig_cloud.get_role("heat_stack_owner"):
- self.role = self.orig_cloud.create_role("heat_stack_owner")
- self.orig_cloud.grant_role(
- "heat_stack_owner", user=self.project.user.id,
- project=self.project.project.id,
- domain=self.project.domain.id)
- creds_overrides = dict(
- username=self.project.user.name,
- project_name=self.project.project.name,
- project_id=self.project.project.id,
- password=self.project.password)
- self.os_creds = kwargs.get('os_creds') or snaps_utils.get_credentials(
- overrides=creds_overrides)
- if 'ext_net_name' in kwargs:
- self.ext_net_name = kwargs['ext_net_name']
- else:
- self.ext_net_name = snaps_utils.get_ext_net_name(self.os_creds)
-
- self.netconf_override = None
- if hasattr(config.CONF, 'snaps_network_config'):
- self.netconf_override = getattr(
- config.CONF, 'snaps_network_config')
-
- self.use_fip = (
- getattr(config.CONF, 'snaps_use_floating_ips') == 'True')
- self.use_keystone = (
- getattr(config.CONF, 'snaps_use_keystone') == 'True')
-
- self.flavor_metadata = getattr(config.CONF, 'snaps_flavor_extra_specs',
- None)
- self.logger.info("Using flavor metadata '%s'", self.flavor_metadata)
-
- self.image_metadata = None
- if hasattr(config.CONF, 'snaps_images'):
- self.image_metadata = getattr(config.CONF, 'snaps_images')
-
- def clean(self):
- """Cleanup of OpenStack resources. Should be called on completion."""
- try:
- super(SnapsTestRunner, self).clean()
- assert self.orig_cloud
- assert self.project
- if self.role:
- self.orig_cloud.delete_role(self.role.id)
- self.project.clean()
- except Exception: # pylint: disable=broad-except
- self.__logger.exception("Cannot clean all resources")
-
- def check_requirements(self):
- """Skip if OpenStack Rocky or newer."""
- try:
- cloud_config = os_client_config.get_config()
- cloud = shade.OpenStackCloud(cloud_config=cloud_config)
- if functest_utils.get_nova_version(cloud) > (2, 60):
- self.is_skipped = True
- except Exception: # pylint: disable=broad-except
- pass
diff --git a/functest/opnfv_tests/openstack/snaps/snaps_utils.py b/functest/opnfv_tests/openstack/snaps/snaps_utils.py
deleted file mode 100644
index f4a6e2ea0..000000000
--- a/functest/opnfv_tests/openstack/snaps/snaps_utils.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2015 All rights reserved
-# This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-
-"""Some common utils wrapping snaps functions"""
-
-from snaps.openstack.tests import openstack_tests
-from snaps.openstack.utils import neutron_utils
-from snaps.openstack.utils import nova_utils
-
-from functest.utils import config
-from functest.utils import constants
-from functest.utils import env
-
-
-def get_ext_net_name(os_creds):
- """
- Returns the configured external network name or
- the first retrieved external network name
- :param: os_creds: an instance of snaps OSCreds object
- :return:
- """
- neutron = neutron_utils.neutron_client(os_creds)
- ext_nets = neutron_utils.get_external_networks(neutron)
- if env.get('EXTERNAL_NETWORK'):
- extnet_config = env.get('EXTERNAL_NETWORK')
- for ext_net in ext_nets:
- if ext_net.name == extnet_config:
- return extnet_config
- return ext_nets[0].name if ext_nets else ""
-
-
-def get_active_compute_cnt(os_creds):
- """
- Returns the number of active compute servers
- :param: os_creds: an instance of snaps OSCreds object
- :return: the number of active compute servers
- """
- nova = nova_utils.nova_client(os_creds)
- computes = nova_utils.get_availability_zone_hosts(nova, zone_name='nova')
- return len(computes)
-
-
-def get_credentials(proxy_settings_str=None, ssh_proxy_cmd=None,
- overrides=None):
- """
- Returns snaps OSCreds object instance
- :param: proxy_settings_str: proxy settings string <host>:<port>
- :param: ssh_proxy_cmd: the SSH proxy command for the environment
- :param overrides: dict() values to override in credentials
- :return: an instance of snaps OSCreds object
- """
- creds_override = {}
- if hasattr(config.CONF, 'snaps_os_creds_override'):
- creds_override.update(getattr(config.CONF, 'snaps_os_creds_override'))
- if overrides:
- creds_override.update(overrides)
- os_creds = openstack_tests.get_credentials(
- os_env_file=constants.ENV_FILE, proxy_settings_str=proxy_settings_str,
- ssh_proxy_cmd=ssh_proxy_cmd, overrides=creds_override)
- return os_creds
diff --git a/functest/opnfv_tests/openstack/tempest/conf_utils.py b/functest/opnfv_tests/openstack/tempest/conf_utils.py
deleted file mode 100644
index 60d7f3218..000000000
--- a/functest/opnfv_tests/openstack/tempest/conf_utils.py
+++ /dev/null
@@ -1,271 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2015 All rights reserved
-# This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-
-"""Tempest configuration utilities."""
-
-from __future__ import print_function
-
-import json
-import logging
-import fileinput
-import os
-import subprocess
-
-import pkg_resources
-from six.moves import configparser
-import yaml
-
-from functest.utils import config
-from functest.utils import env
-from functest.utils import functest_utils
-
-
-RALLY_CONF_PATH = "/etc/rally/rally.conf"
-RALLY_AARCH64_PATCH_PATH = pkg_resources.resource_filename(
- 'functest', 'ci/rally_aarch64_patch.conf')
-GLANCE_IMAGE_PATH = os.path.join(
- getattr(config.CONF, 'dir_functest_images'),
- getattr(config.CONF, 'openstack_image_file_name'))
-TEMPEST_CUSTOM = pkg_resources.resource_filename(
- 'functest', 'opnfv_tests/openstack/tempest/custom_tests/test_list.txt')
-TEMPEST_BLACKLIST = pkg_resources.resource_filename(
- 'functest', 'opnfv_tests/openstack/tempest/custom_tests/blacklist.txt')
-TEMPEST_CONF_YAML = pkg_resources.resource_filename(
- 'functest', 'opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml')
-
-CI_INSTALLER_TYPE = env.get('INSTALLER_TYPE')
-
-""" logging configuration """
-LOGGER = logging.getLogger(__name__)
-
-
-def create_rally_deployment(environ=None):
- """Create new rally deployment"""
- # set the architecture to default
- pod_arch = env.get("POD_ARCH")
- arch_filter = ['aarch64']
-
- if pod_arch and pod_arch in arch_filter:
- LOGGER.info("Apply aarch64 specific to rally config...")
- with open(RALLY_AARCH64_PATCH_PATH, "r") as pfile:
- rally_patch_conf = pfile.read()
-
- for line in fileinput.input(RALLY_CONF_PATH):
- print(line, end=' ')
- if "cirros|testvm" in line:
- print(rally_patch_conf)
-
- LOGGER.info("Creating Rally environment...")
-
- try:
- cmd = ['rally', 'deployment', 'destroy',
- '--deployment',
- str(getattr(config.CONF, 'rally_deployment_name'))]
- output = subprocess.check_output(cmd)
- LOGGER.info("%s\n%s", " ".join(cmd), output)
- except subprocess.CalledProcessError:
- pass
-
- cmd = ['rally', 'deployment', 'create', '--fromenv',
- '--name', str(getattr(config.CONF, 'rally_deployment_name'))]
- output = subprocess.check_output(cmd, env=environ)
- LOGGER.info("%s\n%s", " ".join(cmd), output)
-
- cmd = ['rally', 'deployment', 'check']
- output = subprocess.check_output(cmd)
- LOGGER.info("%s\n%s", " ".join(cmd), output)
- return get_verifier_deployment_id()
-
-
-def create_verifier():
- """Create new verifier"""
- LOGGER.info("Create verifier from existing repo...")
- cmd = ['rally', 'verify', 'delete-verifier',
- '--id', str(getattr(config.CONF, 'tempest_verifier_name')),
- '--force']
- try:
- output = subprocess.check_output(cmd)
- LOGGER.info("%s\n%s", " ".join(cmd), output)
- except subprocess.CalledProcessError:
- pass
-
- cmd = ['rally', 'verify', 'create-verifier',
- '--source', str(getattr(config.CONF, 'dir_repo_tempest')),
- '--name', str(getattr(config.CONF, 'tempest_verifier_name')),
- '--type', 'tempest', '--system-wide']
- output = subprocess.check_output(cmd)
- LOGGER.info("%s\n%s", " ".join(cmd), output)
- return get_verifier_id()
-
-
-def get_verifier_id():
- """
- Returns verifier id for current Tempest
- """
- cmd = ("rally verify list-verifiers | awk '/" +
- getattr(config.CONF, 'tempest_verifier_name') +
- "/ {print $2}'")
- proc = subprocess.Popen(cmd, shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- verifier_uuid = proc.stdout.readline().rstrip()
- return verifier_uuid
-
-
-def get_verifier_deployment_id():
- """
- Returns deployment id for active Rally deployment
- """
- cmd = ("rally deployment list | awk '/" +
- getattr(config.CONF, 'rally_deployment_name') +
- "/ {print $2}'")
- proc = subprocess.Popen(cmd, shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- deployment_uuid = proc.stdout.readline().rstrip()
- return deployment_uuid
-
-
-def get_verifier_repo_dir(verifier_id):
- """
- Returns installed verifier repo directory for Tempest
- """
- return os.path.join(getattr(config.CONF, 'dir_rally_inst'),
- 'verification',
- 'verifier-{}'.format(verifier_id),
- 'repo')
-
-
-def get_verifier_deployment_dir(verifier_id, deployment_id):
- """
- Returns Rally deployment directory for current verifier
- """
- return os.path.join(getattr(config.CONF, 'dir_rally_inst'),
- 'verification',
- 'verifier-{}'.format(verifier_id),
- 'for-deployment-{}'.format(deployment_id))
-
-
-def update_tempest_conf_file(conf_file, rconfig):
- """Update defined paramters into tempest config file"""
- with open(TEMPEST_CONF_YAML) as yfile:
- conf_yaml = yaml.safe_load(yfile)
- if conf_yaml:
- sections = rconfig.sections()
- for section in conf_yaml:
- if section not in sections:
- rconfig.add_section(section)
- sub_conf = conf_yaml.get(section)
- for key, value in sub_conf.items():
- rconfig.set(section, key, value)
-
- with open(conf_file, 'wb') as config_file:
- rconfig.write(config_file)
-
-
-def configure_tempest_update_params(
- tempest_conf_file, image_id=None, flavor_id=None,
- compute_cnt=1, image_alt_id=None, flavor_alt_id=None,
- admin_role_name='admin', cidr='192.168.120.0/24',
- domain_id='default'):
- # pylint: disable=too-many-branches,too-many-arguments,too-many-statements
- """
- Add/update needed parameters into tempest.conf file
- """
- LOGGER.debug("Updating selected tempest.conf parameters...")
- rconfig = configparser.RawConfigParser()
- rconfig.read(tempest_conf_file)
- rconfig.set('compute', 'volume_device_name', env.get('VOLUME_DEVICE_NAME'))
- if image_id is not None:
- rconfig.set('compute', 'image_ref', image_id)
- if image_alt_id is not None:
- rconfig.set('compute', 'image_ref_alt', image_alt_id)
- if flavor_id is not None:
- rconfig.set('compute', 'flavor_ref', flavor_id)
- if flavor_alt_id is not None:
- rconfig.set('compute', 'flavor_ref_alt', flavor_alt_id)
- if compute_cnt > 1:
- # enable multinode tests
- rconfig.set('compute', 'min_compute_nodes', compute_cnt)
- rconfig.set('compute-feature-enabled', 'live_migration', True)
- rconfig.set('compute-feature-enabled', 'shelve', False)
- filters = ['RetryFilter', 'AvailabilityZoneFilter', 'ComputeFilter',
- 'ComputeCapabilitiesFilter', 'ImagePropertiesFilter',
- 'ServerGroupAntiAffinityFilter', 'ServerGroupAffinityFilter']
- rconfig.set(
- 'compute-feature-enabled', 'scheduler_available_filters',
- functest_utils.convert_list_to_ini(filters))
- if os.environ.get('OS_REGION_NAME'):
- rconfig.set('identity', 'region', os.environ.get('OS_REGION_NAME'))
- if env.get("NEW_USER_ROLE").lower() != "member":
- rconfig.set(
- 'auth', 'tempest_roles',
- functest_utils.convert_list_to_ini([env.get("NEW_USER_ROLE")]))
- if not json.loads(env.get("USE_DYNAMIC_CREDENTIALS").lower()):
- rconfig.set('auth', 'use_dynamic_credentials', False)
- account_file = os.path.join(
- getattr(config.CONF, 'dir_functest_data'), 'accounts.yaml')
- assert os.path.exists(
- account_file), "{} doesn't exist".format(account_file)
- rconfig.set('auth', 'test_accounts_file', account_file)
- rconfig.set('identity', 'auth_version', 'v3')
- rconfig.set('identity', 'admin_role', admin_role_name)
- rconfig.set('identity', 'admin_domain_scope', True)
- rconfig.set('identity', 'default_domain_id', domain_id)
- rconfig.set('identity-feature-enabled', 'api_v2', False)
- rconfig.set('identity-feature-enabled', 'api_v2_admin', False)
- if not rconfig.has_section('network'):
- rconfig.add_section('network')
- rconfig.set('network', 'default_network', cidr)
- rconfig.set('network', 'project_network_cidr', cidr)
- rconfig.set('network', 'project_networks_reachable', False)
- rconfig.set(
- 'validation', 'ssh_timeout',
- getattr(config.CONF, 'tempest_validation_ssh_timeout'))
- rconfig.set('object-storage', 'operator_role',
- getattr(config.CONF, 'tempest_object_storage_operator_role'))
- if not rconfig.has_section('volume'):
- rconfig.add_section('volume')
- rconfig.set('volume', 'storage_protocol', env.get('STORAGE_PROTOCOL'))
- rconfig.set(
- 'identity', 'v3_endpoint_type',
- os.environ.get('OS_INTERFACE', 'public'))
-
- sections = rconfig.sections()
- services_list = [
- 'compute', 'volume', 'image', 'network', 'data-processing',
- 'object-storage', 'orchestration']
- for service in services_list:
- if service not in sections:
- rconfig.add_section(service)
- rconfig.set(
- service, 'endpoint_type', os.environ.get('OS_INTERFACE', 'public'))
-
- LOGGER.debug('Add/Update required params defined in tempest_conf.yaml '
- 'into tempest.conf file')
- update_tempest_conf_file(tempest_conf_file, rconfig)
-
-
-def configure_verifier(deployment_dir):
- """
- Execute rally verify configure-verifier, which generates tempest.conf
- """
- cmd = ['rally', 'verify', 'configure-verifier', '--reconfigure',
- '--id', str(getattr(config.CONF, 'tempest_verifier_name'))]
- output = subprocess.check_output(cmd)
- LOGGER.info("%s\n%s", " ".join(cmd), output)
-
- LOGGER.debug("Looking for tempest.conf file...")
- tempest_conf_file = os.path.join(deployment_dir, "tempest.conf")
- if not os.path.isfile(tempest_conf_file):
- LOGGER.error("Tempest configuration file %s NOT found.",
- tempest_conf_file)
- return None
- return tempest_conf_file
diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
deleted file mode 100644
index bb1aed339..000000000
--- a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-
--
diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml
new file mode 100644
index 000000000..43a77fa3c
--- /dev/null
+++ b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml
@@ -0,0 +1,19 @@
+---
+-
+ scenarios:
+ - os-ovn-nofeature-ha
+ - os-ovn-nofeature-noha
+ tests:
+ - neutron_tempest_plugin.api.admin.test_dhcp_agent_scheduler
+ - neutron_tempest_plugin.api.admin.test_ports.PortTestCasesResourceRequest.test_port_resource_request
+ - neutron_tempest_plugin.api.admin.test_ports.PortTestCasesResourceRequest.test_port_resource_request_empty
+ - neutron_tempest_plugin.api.admin.test_ports.PortTestCasesResourceRequest.test_port_resource_request_inherited_policy
+ - neutron_tempest_plugin.api.admin.test_ports.PortTestCasesResourceRequest.test_port_resource_request_no_provider_net_conflict
+ - neutron_tempest_plugin.api.test_ports.PortsTestJSON.test_create_update_port_with_dns_name
+ - patrole_tempest_plugin.tests.api.network.test_availability_zones_rbac.AvailabilityZoneExtRbacTest.test_list_availability_zone_rbac
+ - patrole_tempest_plugin.tests.api.network.test_agents_rbac.DHCPAgentSchedulersRbacTest.test_add_dhcp_agent_to_network
+ - patrole_tempest_plugin.tests.api.network.test_agents_rbac.DHCPAgentSchedulersRbacTest.test_delete_network_from_dhcp_agent
+ - patrole_tempest_plugin.tests.api.network.test_agents_rbac.DHCPAgentSchedulersRbacTest.test_list_networks_hosted_by_one_dhcp_agent
+ - patrole_tempest_plugin.tests.api.network.test_networks_rbac.NetworksRbacTest.test_create_network_provider_network_type
+ - patrole_tempest_plugin.tests.api.network.test_networks_rbac.NetworksRbacTest.test_create_network_provider_segmentation_id
+ - tempest.api.network.admin.test_dhcp_agent_scheduler
diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml
new file mode 100644
index 000000000..e53b577b2
--- /dev/null
+++ b/functest/opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml
@@ -0,0 +1,15 @@
+---
+-
+ scenarios:
+ - os-*
+ tests:
+ - neutron_tempest_plugin.api.admin.test_floating_ips_admin_actions.FloatingIPAdminTestJSON.test_associate_floating_ip_with_port_from_another_project
+ - neutron_tempest_plugin.api.admin.test_quotas.QuotasTest.test_detail_quotas
+ - neutron_tempest_plugin.api.admin.test_quotas.QuotasTest.test_quotas
+ - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_floatingip_when_quotas_is_full
+ - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_network_when_quotas_is_full
+ - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_port_when_quotas_is_full
+ - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_router_when_quotas_is_full
+ - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_security_group_rule_when_quotas_is_full
+ - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_security_group_when_quotas_is_full
+ - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_subnet_when_quotas_is_full
diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml
index b47a9736a..0ee4ab613 100644
--- a/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml
+++ b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml
@@ -1,13 +1,104 @@
-# This is an empty configuration file to be filled up with the desired options
-# to generate a custom tempest.conf
-# Examples:
-# network-feature-enabled:
-# port_security: True
-
-# volume-feature-enabled:
-# api_v1: False
-
-# validation:
-# image_ssh_user: root
-# ssh_timeout: 300
-
+---
+compute:
+ min_microversion: '2.44'
+ max_microversion: latest
+compute-feature-enabled:
+ attach_encrypted_volume: false
+ block_migration_for_live_migration: false
+ block_migrate_cinder_iscsi: false
+ change_password: false
+ cold_migration: true
+ config_drive: true
+ console_output: true
+ disk_config: true
+ enable_instance_password: true
+ hostname_fqdn_sanitization: true
+ interface_attach: true
+ live_migration: true
+ live_migrate_back_and_forth: false
+ metadata_service: true
+ pause: true
+ personality: false
+ rdp_console: false
+ rescue: true
+ resize: true
+ scheduler_available_filters: "AvailabilityZoneFilter,ComputeFilter,\
+ ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,\
+ ServerGroupAffinityFilter,SameHostFilter,DifferentHostFilter"
+ serial_console: false
+ shelve: true
+ snapshot: true
+ spice_console: false
+ suspend: true
+ swap_volume: false
+ vnc_console: true
+ volume_backed_live_migration: false
+ volume_multiattach: false
+identity:
+ auth_version: v3
+ user_unique_last_password_count: 2
+ user_lockout_duration: 10
+ user_lockout_failure_attempts: 2
+identity-feature-enabled:
+ trust: true
+ api_v2: false
+ api_v2_admin: false
+ security_compliance: true
+ federation: false
+ external_idp: false
+ project_tags: true
+ application_credentials: true
+ access_rules: true
+image-feature-enabled:
+ api_v2: true
+ api_v1: false
+ import_image: false
+network-feature-enabled:
+ port_admin_state_change: true
+ port_security: true
+placement:
+ max_microversion: latest
+validation:
+ image_ssh_user: cirros
+ ssh_timeout: 196
+ ip_version_for_ssh: 4
+ run_validation: true
+volume:
+ max_microversion: latest
+ storage_protocol: ceph
+ manage_volume_ref: source-name,volume-%s
+ manage_snapshot_ref: source-name,snapshot-%s
+volume-feature-enabled:
+ multi_backend: false
+ backup: true
+ snapshot: true
+ clone: true
+ manage_snapshot: true
+ manage_volume: true
+ extend_attached_volume: true
+ extend_attached_encrypted_volume: false
+ consistency_group: false
+ volume_revert: true
+load_balancer:
+ test_with_ipv6: false
+neutron_plugin_options:
+ agent_availability_zone: nova
+ available_type_drivers: flat,geneve,vlan,gre,local,vxlan
+ provider_vlans: public,
+ create_shared_resources: true
+object-storage-feature-enabled:
+ discoverable_apis: "account_quotas,formpost,bulk_upload,bulk_delete,\
+ tempurl,crossdomain,container_quotas,staticweb,account_quotas,slo"
+ object_versioning: true
+ discoverability: true
+ tempurl_digest_hashlib: sha1
+heat_plugin:
+ skip_functional_test_list: EncryptionVolTypeTest
+ skip_scenario_test_list: "AodhAlarmTest,SoftwareConfigIntegrationTest,\
+ VolumeBackupRestoreIntegrationTest,CfnInitIntegrationTest,\
+ LoadBalancerTest"
+ auth_version: 3
+heat_features_enabled:
+ multi_cloud: false
+rbac:
+ enable_rbac: true
diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf_ovn.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf_ovn.yaml
new file mode 100644
index 000000000..6b09d8e5a
--- /dev/null
+++ b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf_ovn.yaml
@@ -0,0 +1,104 @@
+---
+compute:
+ min_microversion: '2.44'
+ max_microversion: latest
+compute-feature-enabled:
+ attach_encrypted_volume: false
+ block_migration_for_live_migration: false
+ block_migrate_cinder_iscsi: false
+ change_password: false
+ cold_migration: true
+ config_drive: true
+ console_output: true
+ disk_config: true
+ enable_instance_password: true
+ hostname_fqdn_sanitization: true
+ interface_attach: true
+ live_migration: true
+ live_migrate_back_and_forth: false
+ metadata_service: true
+ pause: true
+ personality: false
+ rdp_console: false
+ rescue: true
+ resize: true
+ scheduler_available_filters: "AvailabilityZoneFilter,ComputeFilter,\
+ ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,\
+ ServerGroupAffinityFilter,SameHostFilter,DifferentHostFilter"
+ serial_console: false
+ shelve: true
+ snapshot: true
+ spice_console: false
+ suspend: true
+ swap_volume: false
+ vnc_console: true
+ volume_backed_live_migration: false
+ volume_multiattach: false
+identity:
+ auth_version: v3
+ user_unique_last_password_count: 2
+ user_lockout_duration: 10
+ user_lockout_failure_attempts: 2
+identity-feature-enabled:
+ trust: true
+ api_v2: false
+ api_v2_admin: false
+ security_compliance: true
+ federation: false
+ external_idp: false
+ project_tags: true
+ application_credentials: true
+ access_rules: true
+image-feature-enabled:
+ api_v2: true
+ api_v1: false
+ import_image: false
+network-feature-enabled:
+ port_admin_state_change: true
+ port_security: true
+placement:
+ max_microversion: latest
+validation:
+ image_ssh_user: cirros
+ ssh_timeout: 196
+ ip_version_for_ssh: 4
+ run_validation: true
+volume:
+ max_microversion: latest
+ storage_protocol: ceph
+ manage_volume_ref: source-name,volume-%s
+ manage_snapshot_ref: source-name,snapshot-%s
+volume-feature-enabled:
+ multi_backend: false
+ backup: true
+ snapshot: true
+ clone: true
+ manage_snapshot: true
+ manage_volume: true
+ extend_attached_volume: true
+ extend_attached_encrypted_volume: false
+ consistency_group: false
+ volume_revert: true
+load_balancer:
+ test_with_ipv6: false
+neutron_plugin_options:
+ agent_availability_zone: nova
+ available_type_drivers: flat,geneve,vlan,local
+ provider_vlans: public,
+ create_shared_resources: true
+object-storage-feature-enabled:
+ discoverable_apis: "account_quotas,formpost,bulk_upload,bulk_delete,\
+ tempurl,crossdomain,container_quotas,staticweb,account_quotas,slo"
+ object_versioning: true
+ discoverability: true
+ tempurl_digest_hashlib: sha1
+heat_plugin:
+ skip_functional_test_list: EncryptionVolTypeTest
+ skip_scenario_test_list: "AodhAlarmTest,SoftwareConfigIntegrationTest,\
+ VolumeBackupRestoreIntegrationTest,CfnInitIntegrationTest,\
+ LoadBalancerTest"
+ auth_version: 3
+heat_features_enabled:
+ multi_cloud: false
+rbac:
+ enable_rbac: true
diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py
index 910b54615..7233ffd60 100644
--- a/functest/opnfv_tests/openstack/tempest/tempest.py
+++ b/functest/opnfv_tests/openstack/tempest/tempest.py
@@ -12,6 +12,7 @@
from __future__ import division
+import json
import logging
import os
import re
@@ -19,12 +20,13 @@ import shutil
import subprocess
import time
+import pkg_resources
from six.moves import configparser
from xtesting.core import testcase
import yaml
from functest.core import singlevm
-from functest.opnfv_tests.openstack.tempest import conf_utils
+from functest.opnfv_tests.openstack.rally import rally
from functest.utils import config
from functest.utils import env
from functest.utils import functest_utils
@@ -33,16 +35,29 @@ LOGGER = logging.getLogger(__name__)
class TempestCommon(singlevm.VmReady2):
- # pylint: disable=too-many-instance-attributes
+ # pylint: disable=too-many-instance-attributes,too-many-public-methods
"""TempestCommon testcases implementation class."""
visibility = 'public'
- filename_alt = '/home/opnfv/functest/images/cirros-0.4.0-x86_64-disk.img'
+ filename_alt = '/home/opnfv/functest/images/cirros-0.6.1-x86_64-disk.img'
+ shared_network = True
+ tempest_conf_yaml = pkg_resources.resource_filename(
+ 'functest',
+ 'opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml')
+ tempest_custom = pkg_resources.resource_filename(
+ 'functest',
+ 'opnfv_tests/openstack/tempest/custom_tests/test_list.txt')
+ tempest_blacklist = pkg_resources.resource_filename(
+ 'functest',
+ 'opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml')
+ tempest_public_blacklist = pkg_resources.resource_filename(
+ 'functest',
+ 'opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml')
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = 'tempest'
- super(TempestCommon, self).__init__(**kwargs)
+ super().__init__(**kwargs)
assert self.orig_cloud
assert self.cloud
assert self.project
@@ -59,28 +74,10 @@ class TempestCommon(singlevm.VmReady2):
self.orig_cloud.grant_role(
self.role_name, user=self.project.user.id,
domain=self.project.domain.id)
- environ = dict(
- os.environ,
- OS_USERNAME=self.project.user.name,
- OS_PROJECT_NAME=self.project.project.name,
- OS_PROJECT_ID=self.project.project.id,
- OS_PASSWORD=self.project.password)
- try:
- del environ['OS_TENANT_NAME']
- del environ['OS_TENANT_ID']
- except Exception: # pylint: disable=broad-except
- pass
- self.deployment_id = conf_utils.create_rally_deployment(
- environ=environ)
- if not self.deployment_id:
- raise Exception("Deployment create failed")
- self.verifier_id = conf_utils.create_verifier()
- if not self.verifier_id:
- raise Exception("Verifier create failed")
- self.verifier_repo_dir = conf_utils.get_verifier_repo_dir(
- self.verifier_id)
- self.deployment_dir = conf_utils.get_verifier_deployment_dir(
- self.verifier_id, self.deployment_id)
+ self.deployment_id = None
+ self.verifier_id = None
+ self.verifier_repo_dir = None
+ self.deployment_dir = None
self.verification_id = None
self.res_dir = os.path.join(
getattr(config.CONF, 'dir_results'), self.case_name)
@@ -100,9 +97,8 @@ class TempestCommon(singlevm.VmReady2):
'neutron_extensions']
except Exception: # pylint: disable=broad-except
pass
-
- def create_network_resources(self):
- pass
+ self.deny_skipping = kwargs.get("deny_skipping", False)
+ self.tests_count = kwargs.get("tests_count", 0)
def check_services(self):
"""Check the mandatory services."""
@@ -132,7 +128,7 @@ class TempestCommon(singlevm.VmReady2):
@staticmethod
def read_file(filename):
"""Read file and return content as a stripped list."""
- with open(filename) as src:
+ with open(filename, encoding='utf-8') as src:
return [line.strip() for line in src.readlines()]
@staticmethod
@@ -146,22 +142,22 @@ class TempestCommon(singlevm.VmReady2):
}
cmd = ["rally", "verify", "show", "--uuid", verif_id]
LOGGER.info("Showing result for a verification: '%s'.", cmd)
- proc = subprocess.Popen(cmd,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- for line in proc.stdout:
- LOGGER.info(line.rstrip())
- new_line = line.replace(' ', '').split('|')
- if 'Tests' in new_line:
- break
- if 'Testscount' in new_line:
- result['num_tests'] = int(new_line[2])
- elif 'Success' in new_line:
- result['num_success'] = int(new_line[2])
- elif 'Skipped' in new_line:
- result['num_skipped'] = int(new_line[2])
- elif 'Failures' in new_line:
- result['num_failures'] = int(new_line[2])
+ with subprocess.Popen(
+ cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT) as proc:
+ for line in proc.stdout:
+ LOGGER.info(line.decode("utf-8").rstrip())
+ new_line = line.decode("utf-8").replace(' ', '').split('|')
+ if 'Tests' in new_line:
+ break
+ if 'Testscount' in new_line:
+ result['num_tests'] = int(new_line[2])
+ elif 'Success' in new_line:
+ result['num_success'] = int(new_line[2])
+ elif 'Skipped' in new_line:
+ result['num_skipped'] = int(new_line[2])
+ elif 'Failures' in new_line:
+ result['num_failures'] = int(new_line[2])
return result
@staticmethod
@@ -174,60 +170,203 @@ class TempestCommon(singlevm.VmReady2):
shutil.copyfile(conf_file,
os.path.join(res_dir, 'tempest.conf'))
+ @staticmethod
+ def create_verifier():
+ """Create new verifier"""
+ LOGGER.info("Create verifier from existing repo...")
+ cmd = ['rally', 'verify', 'delete-verifier',
+ '--id', str(getattr(config.CONF, 'tempest_verifier_name')),
+ '--force']
+ try:
+ output = subprocess.check_output(cmd)
+ LOGGER.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
+ except subprocess.CalledProcessError:
+ pass
+
+ cmd = ['rally', 'verify', 'create-verifier',
+ '--source', str(getattr(config.CONF, 'dir_repo_tempest')),
+ '--name', str(getattr(config.CONF, 'tempest_verifier_name')),
+ '--type', 'tempest', '--system-wide']
+ output = subprocess.check_output(cmd)
+ LOGGER.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
+ return TempestCommon.get_verifier_id()
+
+ @staticmethod
+ def get_verifier_id():
+ """
+ Returns verifier id for current Tempest
+ """
+ cmd = ("rally verify list-verifiers | awk '/" +
+ getattr(config.CONF, 'tempest_verifier_name') +
+ "/ {print $2}'")
+ with subprocess.Popen(
+ cmd, shell=True, stdout=subprocess.PIPE,
+ stderr=subprocess.DEVNULL) as proc:
+ verifier_uuid = proc.stdout.readline().rstrip()
+ return verifier_uuid.decode("utf-8")
+
+ @staticmethod
+ def get_verifier_repo_dir(verifier_id):
+ """
+ Returns installed verifier repo directory for Tempest
+ """
+ return os.path.join(getattr(config.CONF, 'dir_rally_inst'),
+ 'verification',
+ f'verifier-{verifier_id}',
+ 'repo')
+
+ @staticmethod
+ def get_verifier_deployment_dir(verifier_id, deployment_id):
+ """
+ Returns Rally deployment directory for current verifier
+ """
+ return os.path.join(getattr(config.CONF, 'dir_rally_inst'),
+ 'verification',
+ f'verifier-{verifier_id}',
+ f'for-deployment-{deployment_id}')
+
+ @staticmethod
+ def update_tempest_conf_file(conf_file, rconfig):
+ """Update defined paramters into tempest config file"""
+ with open(TempestCommon.tempest_conf_yaml, encoding='utf-8') as yfile:
+ conf_yaml = yaml.safe_load(yfile)
+ if conf_yaml:
+ sections = rconfig.sections()
+ for section in conf_yaml:
+ if section not in sections:
+ rconfig.add_section(section)
+ sub_conf = conf_yaml.get(section)
+ for key, value in sub_conf.items():
+ rconfig.set(section, key, value)
+
+ with open(conf_file, 'w', encoding='utf-8') as config_file:
+ rconfig.write(config_file)
+
+ @staticmethod
+ def configure_tempest_update_params(
+ tempest_conf_file, image_id=None, flavor_id=None,
+ compute_cnt=1, image_alt_id=None, flavor_alt_id=None,
+ admin_role_name='admin', cidr='192.168.120.0/24',
+ domain_id='default'):
+ # pylint: disable=too-many-branches,too-many-arguments
+ # pylint: disable=too-many-statements,too-many-locals
+ """
+ Add/update needed parameters into tempest.conf file
+ """
+ LOGGER.debug("Updating selected tempest.conf parameters...")
+ rconfig = configparser.RawConfigParser()
+ rconfig.read(tempest_conf_file)
+ rconfig.set(
+ 'compute', 'volume_device_name', env.get('VOLUME_DEVICE_NAME'))
+ if image_id is not None:
+ rconfig.set('compute', 'image_ref', image_id)
+ if image_alt_id is not None:
+ rconfig.set('compute', 'image_ref_alt', image_alt_id)
+ if flavor_id is not None:
+ rconfig.set('compute', 'flavor_ref', flavor_id)
+ if flavor_alt_id is not None:
+ rconfig.set('compute', 'flavor_ref_alt', flavor_alt_id)
+ if compute_cnt > 1:
+ # enable multinode tests
+ rconfig.set('compute', 'min_compute_nodes', compute_cnt)
+ rconfig.set('compute-feature-enabled', 'live_migration', True)
+ if os.environ.get('OS_REGION_NAME'):
+ rconfig.set('identity', 'region', os.environ.get('OS_REGION_NAME'))
+ rconfig.set('identity', 'admin_role', admin_role_name)
+ rconfig.set('identity', 'default_domain_id', domain_id)
+ if not rconfig.has_section('network'):
+ rconfig.add_section('network')
+ rconfig.set('network', 'default_network', cidr)
+ rconfig.set('network', 'project_network_cidr', cidr)
+ rconfig.set('network', 'project_networks_reachable', False)
+ rconfig.set(
+ 'identity', 'v3_endpoint_type',
+ os.environ.get('OS_INTERFACE', 'public'))
+
+ sections = rconfig.sections()
+ services_list = [
+ 'compute', 'volume', 'image', 'network', 'data-processing',
+ 'object-storage', 'orchestration']
+ for service in services_list:
+ if service not in sections:
+ rconfig.add_section(service)
+ rconfig.set(service, 'endpoint_type',
+ os.environ.get('OS_INTERFACE', 'public'))
+
+ LOGGER.debug('Add/Update required params defined in tempest_conf.yaml '
+ 'into tempest.conf file')
+ TempestCommon.update_tempest_conf_file(tempest_conf_file, rconfig)
+
+ @staticmethod
+ def configure_verifier(deployment_dir):
+ """
+ Execute rally verify configure-verifier, which generates tempest.conf
+ """
+ cmd = ['rally', 'verify', 'configure-verifier', '--reconfigure',
+ '--id', str(getattr(config.CONF, 'tempest_verifier_name'))]
+ output = subprocess.check_output(cmd)
+ LOGGER.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
+
+ LOGGER.debug("Looking for tempest.conf file...")
+ tempest_conf_file = os.path.join(deployment_dir, "tempest.conf")
+ if not os.path.isfile(tempest_conf_file):
+ LOGGER.error("Tempest configuration file %s NOT found.",
+ tempest_conf_file)
+ return None
+ return tempest_conf_file
+
def generate_test_list(self, **kwargs):
"""Generate test list based on the test mode."""
LOGGER.debug("Generating test case list...")
self.backup_tempest_config(self.conf_file, '/etc')
if kwargs.get('mode') == 'custom':
- if os.path.isfile(conf_utils.TEMPEST_CUSTOM):
+ if os.path.isfile(self.tempest_custom):
shutil.copyfile(
- conf_utils.TEMPEST_CUSTOM, self.list)
+ self.tempest_custom, self.list)
else:
- raise Exception("Tempest test list file %s NOT found."
- % conf_utils.TEMPEST_CUSTOM)
+ raise Exception(
+ f"Tempest test list file {self.tempest_custom} NOT found.")
else:
testr_mode = kwargs.get(
'mode', r'^tempest\.(api|scenario).*\[.*\bsmoke\b.*\]$')
- cmd = "(cd {0}; stestr list '{1}' >{2} 2>/dev/null)".format(
- self.verifier_repo_dir, testr_mode, self.list)
+ cmd = (f"(cd {self.verifier_repo_dir}; "
+ f"stestr list '{testr_mode}' > {self.list} 2>/dev/null)")
output = subprocess.check_output(cmd, shell=True)
- LOGGER.info("%s\n%s", cmd, output)
+ LOGGER.info("%s\n%s", cmd, output.decode("utf-8"))
os.remove('/etc/tempest.conf')
- def apply_tempest_blacklist(self):
+ def apply_tempest_blacklist(self, black_list):
"""Exclude blacklisted test cases."""
LOGGER.debug("Applying tempest blacklist...")
if os.path.exists(self.raw_list):
os.remove(self.raw_list)
os.rename(self.list, self.raw_list)
cases_file = self.read_file(self.raw_list)
- result_file = open(self.list, 'w')
- black_tests = []
- try:
- deploy_scenario = env.get('DEPLOY_SCENARIO')
- if bool(deploy_scenario):
- # if DEPLOY_SCENARIO is set we read the file
- black_list_file = open(conf_utils.TEMPEST_BLACKLIST)
- black_list_yaml = yaml.safe_load(black_list_file)
- black_list_file.close()
- for item in black_list_yaml:
- scenarios = item['scenarios']
- if deploy_scenario in scenarios:
- tests = item['tests']
- for test in tests:
- black_tests.append(test)
- break
- except Exception: # pylint: disable=broad-except
+ with open(self.list, 'w', encoding='utf-8') as result_file:
black_tests = []
- LOGGER.debug("Tempest blacklist file does not exist.")
+ try:
+ deploy_scenario = env.get('DEPLOY_SCENARIO')
+ if bool(deploy_scenario):
+ # if DEPLOY_SCENARIO is set we read the file
+ with open(black_list, encoding='utf-8') as black_list_file:
+ black_list_yaml = yaml.safe_load(black_list_file)
+ black_list_file.close()
+ for item in black_list_yaml:
+ scenarios = item['scenarios']
+ in_it = rally.RallyBase.in_iterable_re
+ if in_it(deploy_scenario, scenarios):
+ tests = item['tests']
+ black_tests.extend(tests)
+ except Exception: # pylint: disable=broad-except
+ black_tests = []
+ LOGGER.debug("Tempest blacklist file does not exist.")
- for cases_line in cases_file:
- for black_tests_line in black_tests:
- if black_tests_line in cases_line:
- break
- else:
- result_file.write(str(cases_line) + '\n')
- result_file.close()
+ for cases_line in cases_file:
+ for black_tests_line in black_tests:
+ if re.search(black_tests_line, cases_line):
+ break
+ else:
+ result_file.write(str(cases_line) + '\n')
def run_verifier_tests(self, **kwargs):
"""Execute tempest test cases."""
@@ -236,33 +375,31 @@ class TempestCommon(singlevm.VmReady2):
cmd.extend(kwargs.get('option', []))
LOGGER.info("Starting Tempest test suite: '%s'.", cmd)
- f_stdout = open(
- os.path.join(self.res_dir, "tempest.log"), 'w+')
-
- proc = subprocess.Popen(
- cmd,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- bufsize=1)
-
- with proc.stdout:
- for line in iter(proc.stdout.readline, b''):
- if re.search(r"\} tempest\.", line):
- LOGGER.info(line.rstrip())
- elif re.search(r'(?=\(UUID=(.*)\))', line):
- self.verification_id = re.search(
- r'(?=\(UUID=(.*)\))', line).group(1)
- f_stdout.write(line)
- proc.wait()
- f_stdout.close()
+ with open(
+ os.path.join(self.res_dir, "tempest.log"), 'w+',
+ encoding='utf-8') as f_stdout:
+ with subprocess.Popen(
+ cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+ bufsize=1) as proc:
+ with proc.stdout:
+ for line in iter(proc.stdout.readline, b''):
+ if re.search(r"\} tempest\.", line.decode("utf-8")):
+ LOGGER.info(line.rstrip())
+ elif re.search(r'(?=\(UUID=(.*)\))',
+ line.decode("utf-8")):
+ self.verification_id = re.search(
+ r'(?=\(UUID=(.*)\))',
+ line.decode("utf-8")).group(1)
+ f_stdout.write(line.decode("utf-8"))
+ proc.wait()
if self.verification_id is None:
raise Exception('Verification UUID not found')
LOGGER.info('Verification UUID: %s', self.verification_id)
shutil.copy(
- "{}/tempest.log".format(self.deployment_dir),
- "{}/tempest.debug.log".format(self.res_dir))
+ f"{self.deployment_dir}/tempest.log",
+ f"{self.res_dir}/tempest.debug.log")
def parse_verifier_result(self):
"""Parse and save test results."""
@@ -279,8 +416,8 @@ class TempestCommon(singlevm.VmReady2):
LOGGER.error("No test has been executed")
return
- with open(os.path.join(self.res_dir,
- "tempest.log"), 'r') as logfile:
+ with open(os.path.join(self.res_dir, "rally.log"),
+ 'r', encoding='utf-8') as logfile:
output = logfile.read()
success_testcases = []
@@ -292,7 +429,7 @@ class TempestCommon(singlevm.VmReady2):
output):
failed_testcases.append(match)
skipped_testcases = []
- for match in re.findall(r'.*\{\d{1,2}\} (.*?) \.{3} skip:',
+ for match in re.findall(r'.*\{\d{1,2}\} (.*?) \.{3} skip(?::| )',
output):
skipped_testcases.append(match)
@@ -309,24 +446,14 @@ class TempestCommon(singlevm.VmReady2):
LOGGER.info("Tempest %s success_rate is %s%%",
self.case_name, self.result)
- def generate_report(self):
- """Generate verification report."""
- html_file = os.path.join(self.res_dir,
- "tempest-report.html")
- cmd = ["rally", "verify", "report", "--type", "html", "--uuid",
- self.verification_id, "--to", html_file]
- subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
-
def update_rally_regex(self, rally_conf='/etc/rally/rally.conf'):
"""Set image name as tempest img_name_regex"""
rconfig = configparser.RawConfigParser()
rconfig.read(rally_conf)
if not rconfig.has_section('openstack'):
rconfig.add_section('openstack')
- rconfig.set('openstack', 'img_name_regex', '^{}$'.format(
- self.image.name))
- with open(rally_conf, 'wb') as config_file:
+ rconfig.set('openstack', 'img_name_regex', f'^{self.image.name}$')
+ with open(rally_conf, 'w', encoding='utf-8') as config_file:
rconfig.write(config_file)
def update_default_role(self, rally_conf='/etc/rally/rally.conf'):
@@ -339,18 +466,7 @@ class TempestCommon(singlevm.VmReady2):
if not rconfig.has_section('openstack'):
rconfig.add_section('openstack')
rconfig.set('openstack', 'swift_operator_role', role.name)
- with open(rally_conf, 'wb') as config_file:
- rconfig.write(config_file)
-
- def update_rally_logs(self, rally_conf='/etc/rally/rally.conf'):
- """Print rally logs in res dir"""
- if not os.path.exists(self.res_dir):
- os.makedirs(self.res_dir)
- rconfig = configparser.RawConfigParser()
- rconfig.read(rally_conf)
- rconfig.set('DEFAULT', 'log-file', 'rally.log')
- rconfig.set('DEFAULT', 'log_dir', self.res_dir)
- with open(rally_conf, 'wb') as config_file:
+ with open(rally_conf, 'w', encoding='utf-8') as config_file:
rconfig.write(config_file)
@staticmethod
@@ -362,11 +478,78 @@ class TempestCommon(singlevm.VmReady2):
rconfig.remove_option('openstack', 'img_name_regex')
if rconfig.has_option('openstack', 'swift_operator_role'):
rconfig.remove_option('openstack', 'swift_operator_role')
- if rconfig.has_option('DEFAULT', 'log-file'):
- rconfig.remove_option('DEFAULT', 'log-file')
- if rconfig.has_option('DEFAULT', 'log_dir'):
- rconfig.remove_option('DEFAULT', 'log_dir')
- with open(rally_conf, 'wb') as config_file:
+ with open(rally_conf, 'w', encoding='utf-8') as config_file:
+ rconfig.write(config_file)
+
+ def update_auth_section(self):
+ """Update auth section in tempest.conf"""
+ rconfig = configparser.RawConfigParser()
+ rconfig.read(self.conf_file)
+ if not rconfig.has_section("auth"):
+ rconfig.add_section("auth")
+ if env.get("NEW_USER_ROLE").lower() != "member":
+ tempest_roles = []
+ if rconfig.has_option("auth", "tempest_roles"):
+ tempest_roles = functest_utils.convert_ini_to_list(
+ rconfig.get("auth", "tempest_roles"))
+ rconfig.set(
+ 'auth', 'tempest_roles',
+ functest_utils.convert_list_to_ini(
+ [env.get("NEW_USER_ROLE")] + tempest_roles))
+ if not json.loads(env.get("USE_DYNAMIC_CREDENTIALS").lower()):
+ rconfig.set('auth', 'use_dynamic_credentials', False)
+ account_file = os.path.join(
+ getattr(config.CONF, 'dir_functest_data'), 'accounts.yaml')
+ assert os.path.exists(
+ account_file), f"{account_file} doesn't exist"
+ rconfig.set('auth', 'test_accounts_file', account_file)
+ if env.get('NO_TENANT_NETWORK').lower() == 'true':
+ rconfig.set('auth', 'create_isolated_networks', False)
+ with open(self.conf_file, 'w', encoding='utf-8') as config_file:
+ rconfig.write(config_file)
+
+ def update_network_section(self):
+ """Update network section in tempest.conf"""
+ rconfig = configparser.RawConfigParser()
+ rconfig.read(self.conf_file)
+ if self.ext_net:
+ if not rconfig.has_section('network'):
+ rconfig.add_section('network')
+ rconfig.set('network', 'public_network_id', self.ext_net.id)
+ rconfig.set('network', 'floating_network_name', self.ext_net.name)
+ rconfig.set('network-feature-enabled', 'floating_ips', True)
+ else:
+ if not rconfig.has_section('network-feature-enabled'):
+ rconfig.add_section('network-feature-enabled')
+ rconfig.set('network-feature-enabled', 'floating_ips', False)
+ with open(self.conf_file, 'w', encoding='utf-8') as config_file:
+ rconfig.write(config_file)
+
+ def update_compute_section(self):
+ """Update compute section in tempest.conf"""
+ rconfig = configparser.RawConfigParser()
+ rconfig.read(self.conf_file)
+ if not rconfig.has_section('compute'):
+ rconfig.add_section('compute')
+ rconfig.set(
+ 'compute', 'fixed_network_name',
+ self.network.name if self.network else env.get("EXTERNAL_NETWORK"))
+ with open(self.conf_file, 'w', encoding='utf-8') as config_file:
+ rconfig.write(config_file)
+
+ def update_validation_section(self):
+ """Update validation section in tempest.conf"""
+ rconfig = configparser.RawConfigParser()
+ rconfig.read(self.conf_file)
+ if not rconfig.has_section('validation'):
+ rconfig.add_section('validation')
+ rconfig.set(
+ 'validation', 'connect_method',
+ 'floating' if self.ext_net else 'fixed')
+ rconfig.set(
+ 'validation', 'network_for_ssh',
+ self.network.name if self.network else env.get("EXTERNAL_NETWORK"))
+ with open(self.conf_file, 'w', encoding='utf-8') as config_file:
rconfig.write(config_file)
def update_scenario_section(self):
@@ -374,13 +557,12 @@ class TempestCommon(singlevm.VmReady2):
rconfig = configparser.RawConfigParser()
rconfig.read(self.conf_file)
filename = getattr(
- config.CONF, '{}_image'.format(self.case_name), self.filename)
+ config.CONF, f'{self.case_name}_image', self.filename)
if not rconfig.has_section('scenario'):
rconfig.add_section('scenario')
- rconfig.set('scenario', 'img_file', os.path.basename(filename))
- rconfig.set('scenario', 'img_dir', os.path.dirname(filename))
+ rconfig.set('scenario', 'img_file', filename)
rconfig.set('scenario', 'img_disk_format', getattr(
- config.CONF, '{}_image_format'.format(self.case_name),
+ config.CONF, f'{self.case_name}_image_format',
self.image_format))
extra_properties = self.extra_properties.copy()
if env.get('IMAGE_PROPERTIES'):
@@ -388,12 +570,24 @@ class TempestCommon(singlevm.VmReady2):
functest_utils.convert_ini_to_dict(
env.get('IMAGE_PROPERTIES')))
extra_properties.update(
- getattr(config.CONF, '{}_extra_properties'.format(
- self.case_name), {}))
+ getattr(config.CONF, f'{self.case_name}_extra_properties', {}))
rconfig.set(
'scenario', 'img_properties',
functest_utils.convert_dict_to_ini(extra_properties))
- with open(self.conf_file, 'wb') as config_file:
+ with open(self.conf_file, 'w', encoding='utf-8') as config_file:
+ rconfig.write(config_file)
+
+ def update_dashboard_section(self):
+ """Update dashboard section in tempest.conf"""
+ rconfig = configparser.RawConfigParser()
+ rconfig.read(self.conf_file)
+ if env.get('DASHBOARD_URL'):
+ if not rconfig.has_section('dashboard'):
+ rconfig.add_section('dashboard')
+ rconfig.set('dashboard', 'dashboard_url', env.get('DASHBOARD_URL'))
+ else:
+ rconfig.set('service_available', 'horizon', False)
+ with open(self.conf_file, 'w', encoding='utf-8') as config_file:
rconfig.write(config_file)
def configure(self, **kwargs): # pylint: disable=unused-argument
@@ -403,16 +597,28 @@ class TempestCommon(singlevm.VmReady2):
"""
if not os.path.exists(self.res_dir):
os.makedirs(self.res_dir)
- compute_cnt = len(self.cloud.list_hypervisors())
+ self.deployment_id = rally.RallyBase.create_rally_deployment(
+ environ=self.project.get_environ())
+ if not self.deployment_id:
+ raise Exception("Deployment create failed")
+ self.verifier_id = self.create_verifier()
+ if not self.verifier_id:
+ raise Exception("Verifier create failed")
+ self.verifier_repo_dir = self.get_verifier_repo_dir(
+ self.verifier_id)
+ self.deployment_dir = self.get_verifier_deployment_dir(
+ self.verifier_id, self.deployment_id)
+ compute_cnt = self.count_hypervisors() if self.count_hypervisors(
+ ) <= 10 else 10
self.image_alt = self.publish_image_alt()
self.flavor_alt = self.create_flavor_alt()
LOGGER.debug("flavor: %s", self.flavor_alt)
- self.conf_file = conf_utils.configure_verifier(self.deployment_dir)
+ self.conf_file = self.configure_verifier(self.deployment_dir)
if not self.conf_file:
raise Exception("Tempest verifier configuring failed")
- conf_utils.configure_tempest_update_params(
+ self.configure_tempest_update_params(
self.conf_file,
image_id=self.image.id,
flavor_id=self.flavor.id,
@@ -421,26 +627,39 @@ class TempestCommon(singlevm.VmReady2):
flavor_alt_id=self.flavor_alt.id,
admin_role_name=self.role_name, cidr=self.cidr,
domain_id=self.project.domain.id)
+ self.update_auth_section()
+ self.update_network_section()
+ self.update_compute_section()
+ self.update_validation_section()
self.update_scenario_section()
+ self.update_dashboard_section()
self.backup_tempest_config(self.conf_file, self.res_dir)
def run(self, **kwargs):
self.start_time = time.time()
try:
- assert super(TempestCommon, self).run(
+ assert super().run(
**kwargs) == testcase.TestCase.EX_OK
if not os.path.exists(self.res_dir):
os.makedirs(self.res_dir)
self.update_rally_regex()
self.update_default_role()
- self.update_rally_logs()
+ rally.RallyBase.update_rally_logs(self.res_dir)
shutil.copy("/etc/rally/rally.conf", self.res_dir)
self.configure(**kwargs)
self.generate_test_list(**kwargs)
- self.apply_tempest_blacklist()
+ self.apply_tempest_blacklist(TempestCommon.tempest_blacklist)
+ if env.get('PUBLIC_ENDPOINT_ONLY').lower() == 'true':
+ self.apply_tempest_blacklist(
+ TempestCommon.tempest_public_blacklist)
self.run_verifier_tests(**kwargs)
self.parse_verifier_result()
- self.generate_report()
+ rally.RallyBase.verify_report(
+ os.path.join(self.res_dir, "tempest-report.html"),
+ self.verification_id)
+ rally.RallyBase.verify_report(
+ os.path.join(self.res_dir, "tempest-report.xml"),
+ self.verification_id, "junit-xml")
res = testcase.TestCase.EX_OK
except Exception: # pylint: disable=broad-except
LOGGER.exception('Error with run')
@@ -454,8 +673,102 @@ class TempestCommon(singlevm.VmReady2):
Cleanup all OpenStack objects. Should be called on completion.
"""
self.clean_rally_conf()
+ rally.RallyBase.clean_rally_logs()
if self.image_alt:
self.cloud.delete_image(self.image_alt)
if self.flavor_alt:
self.orig_cloud.delete_flavor(self.flavor_alt.id)
- super(TempestCommon, self).clean()
+ super().clean()
+
+ def is_successful(self):
+ """The overall result of the test."""
+ skips = self.details.get("skipped_number", 0)
+ if skips > 0 and self.deny_skipping:
+ return testcase.TestCase.EX_TESTCASE_FAILED
+ if self.tests_count and (
+ self.details.get("tests_number", 0) != self.tests_count):
+ return testcase.TestCase.EX_TESTCASE_FAILED
+ return super().is_successful()
+
+
+class TempestHeat(TempestCommon):
+ """Tempest Heat testcase implementation class."""
+
+ filename_alt = ('/home/opnfv/functest/images/'
+ 'Fedora-Cloud-Base-30-1.2.x86_64.qcow2')
+ flavor_alt_ram = 512
+ flavor_alt_vcpus = 1
+ flavor_alt_disk = 4
+
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.user2 = self.orig_cloud.create_user(
+ name=f'{self.case_name}-user2_{self.project.guid}',
+ password=self.project.password,
+ domain_id=self.project.domain.id)
+ self.orig_cloud.grant_role(
+ self.role_name, user=self.user2.id,
+ project=self.project.project.id, domain=self.project.domain.id)
+ if not self.orig_cloud.get_role("heat_stack_owner"):
+ self.role = self.orig_cloud.create_role("heat_stack_owner")
+ self.orig_cloud.grant_role(
+ "heat_stack_owner", user=self.user2.id,
+ project=self.project.project.id,
+ domain=self.project.domain.id)
+
+ def configure(self, **kwargs):
+ assert self.user2
+ super().configure(**kwargs)
+ rconfig = configparser.RawConfigParser()
+ rconfig.read(self.conf_file)
+ if not rconfig.has_section('heat_plugin'):
+ rconfig.add_section('heat_plugin')
+ # It fails if region and domain ids are unset
+ rconfig.set(
+ 'heat_plugin', 'region',
+ os.environ.get('OS_REGION_NAME', 'RegionOne'))
+ rconfig.set('heat_plugin', 'auth_url', os.environ["OS_AUTH_URL"])
+ rconfig.set('heat_plugin', 'project_domain_id', self.project.domain.id)
+ rconfig.set('heat_plugin', 'user_domain_id', self.project.domain.id)
+ rconfig.set(
+ 'heat_plugin', 'project_domain_name', self.project.domain.name)
+ rconfig.set(
+ 'heat_plugin', 'user_domain_name', self.project.domain.name)
+ rconfig.set('heat_plugin', 'username', self.user2.name)
+ rconfig.set('heat_plugin', 'password', self.project.password)
+ rconfig.set('heat_plugin', 'project_name', self.project.project.name)
+ rconfig.set('heat_plugin', 'admin_username', self.project.user.name)
+ rconfig.set('heat_plugin', 'admin_password', self.project.password)
+ rconfig.set(
+ 'heat_plugin', 'admin_project_name', self.project.project.name)
+ rconfig.set('heat_plugin', 'image_ref', self.image_alt.id)
+ rconfig.set('heat_plugin', 'instance_type', self.flavor_alt.id)
+ rconfig.set('heat_plugin', 'minimal_image_ref', self.image.id)
+ rconfig.set('heat_plugin', 'minimal_instance_type', self.flavor.id)
+ if self.ext_net:
+ rconfig.set(
+ 'heat_plugin', 'floating_network_name', self.ext_net.name)
+ if self.network:
+ rconfig.set('heat_plugin', 'fixed_network_name', self.network.name)
+ rconfig.set('heat_plugin', 'fixed_subnet_name', self.subnet.name)
+ rconfig.set('heat_plugin', 'network_for_ssh', self.network.name)
+ else:
+ LOGGER.warning(
+ 'No tenant network created. '
+ 'Trying EXTERNAL_NETWORK as a fallback')
+ rconfig.set(
+ 'heat_plugin', 'fixed_network_name',
+ env.get("EXTERNAL_NETWORK"))
+ rconfig.set(
+ 'heat_plugin', 'network_for_ssh', env.get("EXTERNAL_NETWORK"))
+ with open(self.conf_file, 'w', encoding='utf-8') as config_file:
+ rconfig.write(config_file)
+ self.backup_tempest_config(self.conf_file, self.res_dir)
+
+ def clean(self):
+ """
+ Cleanup all OpenStack objects. Should be called on completion.
+ """
+ super().clean()
+ if self.user2:
+ self.orig_cloud.delete_user(self.user2.id)
diff --git a/functest/opnfv_tests/openstack/vgpu/__init__.py b/functest/opnfv_tests/openstack/vgpu/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/functest/opnfv_tests/openstack/vgpu/__init__.py
+++ /dev/null
diff --git a/functest/opnfv_tests/openstack/vgpu/vgpu.py b/functest/opnfv_tests/openstack/vgpu/vgpu.py
deleted file mode 100644
index a900eb203..000000000
--- a/functest/opnfv_tests/openstack/vgpu/vgpu.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2018 Kontron and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-
-"""vGPU testcase implementation."""
-
-from __future__ import division
-
-import logging
-
-from functest.core import singlevm
-
-
-class vGPU(singlevm.SingleVm2):
- """OpenStack vGPU Test Case."""
-
- __logger = logging.getLogger(__name__)
-
- filename = ('/home/opnfv/functest/images/'
- 'ubuntu-16.04-server-cloudimg-amd64-disk1.img')
- flavor_ram = 4096
- flavor_vcpus = 2
- flavor_disk = 40
- flavor_extra_specs = {'resources:VGPU': '1'}
- username = 'ubuntu'
- ssh_connect_loops = 12
- create_server_timeout = 300
-
- def __init__(self, **kwargs):
- """Initialize vGPU testcase object."""
- if "case_name" not in kwargs:
- kwargs["case_name"] = "vgpu"
- super(vGPU, self).__init__(**kwargs)
-
- def execute(self):
- """
- Test if the vGPU exist.
- """
- (_, stdout, stderr) = self.ssh.exec_command('lspci')
- lspci_output = stdout.read()
- self.__logger.debug("output:\n%s", stdout.read())
- self.__logger.debug("error:\n%s", stderr.read())
- if ('VGA compatible controller: Intel' in lspci_output or
- 'VGA compatible controller: Nvidia' in lspci_output):
- self.__logger.info("The VM have a vGPU")
- return 0
- else:
- self.__logger.error("The VM haven't any vGPU")
- return 1
diff --git a/functest/opnfv_tests/openstack/vmtp/vmtp.py b/functest/opnfv_tests/openstack/vmtp/vmtp.py
index 8831078db..9833cc72a 100644
--- a/functest/opnfv_tests/openstack/vmtp/vmtp.py
+++ b/functest/opnfv_tests/openstack/vmtp/vmtp.py
@@ -33,6 +33,7 @@ from xtesting.core import testcase
from functest.core import singlevm
from functest.utils import env
+from functest.utils import functest_utils
class Vmtp(singlevm.VmReady2):
@@ -49,15 +50,23 @@ class Vmtp(singlevm.VmReady2):
flavor_ram = 2048
flavor_vcpus = 1
flavor_disk = 0
+ create_server_timeout = 300
+ ssh_retry_timeout = 240
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = 'vmtp'
- super(Vmtp, self).__init__(**kwargs)
- self.config = "{}/vmtp.conf".format(self.res_dir)
+ super().__init__(**kwargs)
+ self.config = f"{self.res_dir}/vmtp.conf"
(_, self.privkey_filename) = tempfile.mkstemp()
(_, self.pubkey_filename) = tempfile.mkstemp()
+ def check_requirements(self):
+ if self.count_hypervisors() < 2:
+ self.__logger.warning("Vmtp requires at least 2 hypervisors")
+ self.is_skipped = True
+ self.project.clean()
+
def create_network_resources(self):
"""Create router
@@ -68,7 +77,7 @@ class Vmtp(singlevm.VmReady2):
assert self.cloud
assert self.ext_net
self.router = self.cloud.create_router(
- name='{}-router_{}'.format(self.case_name, self.guid),
+ name=f'{self.case_name}-router_{self.guid}',
ext_gateway_net_id=self.ext_net.id)
self.__logger.debug("router: %s", self.router)
@@ -78,13 +87,13 @@ class Vmtp(singlevm.VmReady2):
Raises: Exception on error
"""
assert self.cloud
- name = "vmtp_{}".format(self.guid)
+ name = f"vmtp_{self.guid}"
self.__logger.info("Creating keypair with name: '%s'", name)
keypair = self.cloud.create_keypair(name)
self.__logger.debug("keypair: %s", keypair)
- with open(self.privkey_filename, 'w') as key_file:
+ with open(self.privkey_filename, 'w', encoding='utf-8') as key_file:
key_file.write(keypair.private_key)
- with open(self.pubkey_filename, 'w') as key_file:
+ with open(self.pubkey_filename, 'w', encoding='utf-8') as key_file:
key_file.write(keypair.public_key)
self.cloud.delete_keypair(keypair.id)
@@ -97,27 +106,28 @@ class Vmtp(singlevm.VmReady2):
if not os.path.exists(self.res_dir):
os.makedirs(self.res_dir)
cmd = ['vmtp', '-sc']
- output = subprocess.check_output(cmd)
+ output = subprocess.check_output(cmd).decode("utf-8")
self.__logger.info("%s\n%s", " ".join(cmd), output)
- with open(self.config, "w+") as conf:
- vmtp_conf = yaml.load(output)
+ with open(self.config, "w+", encoding='utf-8') as conf:
+ vmtp_conf = yaml.full_load(output)
vmtp_conf["private_key_file"] = self.privkey_filename
vmtp_conf["public_key_file"] = self.pubkey_filename
vmtp_conf["image_name"] = str(self.image.name)
vmtp_conf["router_name"] = str(self.router.name)
vmtp_conf["flavor_type"] = str(self.flavor.name)
vmtp_conf["internal_network_name"] = [
- "pns-internal-net_{}".format(self.guid),
- "pns-internal-net2_{}".format(self.guid)]
- vmtp_conf["vm_name_client"] = "TestClient_{}".format(self.guid)
- vmtp_conf["vm_name_server"] = "TestServer_{}".format(self.guid)
- vmtp_conf["security_group_name"] = "pns-security{}".format(
- self.guid)
+ f"pns-internal-net_{self.guid}",
+ f"pns-internal-net2_{self.guid}"]
+ vmtp_conf["vm_name_client"] = f"TestClient_{self.guid}"
+ vmtp_conf["vm_name_server"] = f"TestServer_{self.guid}"
+ vmtp_conf["security_group_name"] = f"pns-security{self.guid}"
vmtp_conf["dns_nameservers"] = [env.get('NAMESERVER')]
vmtp_conf["generic_retry_count"] = self.create_server_timeout // 2
+ vmtp_conf["ssh_retry_count"] = self.ssh_retry_timeout // 2
conf.write(yaml.dump(vmtp_conf))
def run_vmtp(self):
+ # pylint: disable=unexpected-keyword-arg
"""Run Vmtp and generate charts
Raises: Exception on error
@@ -128,22 +138,34 @@ class Vmtp(singlevm.VmReady2):
OS_USERNAME=self.project.user.name,
OS_PROJECT_NAME=self.project.project.name,
OS_PROJECT_ID=self.project.project.id,
+ OS_PROJECT_DOMAIN_NAME=self.project.domain.name,
+ OS_USER_DOMAIN_NAME=self.project.domain.name,
OS_PASSWORD=self.project.password)
+ if not new_env["OS_AUTH_URL"].endswith(('v3', 'v3/')):
+ new_env["OS_AUTH_URL"] = f'{new_env["OS_AUTH_URL"]}/v3'
try:
del new_env['OS_TENANT_NAME']
del new_env['OS_TENANT_ID']
except Exception: # pylint: disable=broad-except
pass
- cmd = ['vmtp', '-d', '--json', '{}/vmtp.json'.format(self.res_dir),
+ cmd = ['vmtp', '-d', '--json', f'{self.res_dir}/vmtp.json',
'-c', self.config]
+ if env.get("VMTP_HYPERVISORS"):
+ hypervisors = functest_utils.convert_ini_to_list(
+ env.get("VMTP_HYPERVISORS"))
+ for hypervisor in hypervisors:
+ cmd.extend(["--hypervisor", hypervisor])
+ self.__logger.debug("cmd: %s", cmd)
output = subprocess.check_output(
- cmd, stderr=subprocess.STDOUT, env=new_env)
+ cmd, stderr=subprocess.STDOUT, env=new_env).decode("utf-8")
self.__logger.info("%s\n%s", " ".join(cmd), output)
- cmd = ['vmtp_genchart', '-c', '{}/vmtp.html'.format(self.res_dir),
- '{}/vmtp.json'.format(self.res_dir)]
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ cmd = ['vmtp_genchart', '-c', f'{self.res_dir}/vmtp.html',
+ f'{self.res_dir}/vmtp.json']
+ output = subprocess.check_output(
+ cmd, stderr=subprocess.STDOUT).decode("utf-8")
self.__logger.info("%s\n%s", " ".join(cmd), output)
- with open('{}/vmtp.json'.format(self.res_dir), 'r') as res_file:
+ with open(f'{self.res_dir}/vmtp.json', 'r',
+ encoding='utf-8') as res_file:
self.details = json.load(res_file)
def run(self, **kwargs):
@@ -151,7 +173,7 @@ class Vmtp(singlevm.VmReady2):
status = testcase.TestCase.EX_RUN_ERROR
try:
assert self.cloud
- assert super(Vmtp, self).run(**kwargs) == self.EX_OK
+ assert super().run(**kwargs) == self.EX_OK
status = testcase.TestCase.EX_RUN_ERROR
if self.orig_cloud.get_role("admin"):
role_name = "admin"
@@ -170,7 +192,8 @@ class Vmtp(singlevm.VmReady2):
status = testcase.TestCase.EX_OK
except subprocess.CalledProcessError as cpe:
self.__logger.error(
- "Exception when calling %s\n%s", cpe.cmd, cpe.output)
+ "Exception when calling %s\n%s", cpe.cmd,
+ cpe.output.decode("utf-8"))
self.result = 0
except Exception: # pylint: disable=broad-except
self.__logger.exception("Cannot run vmtp")
@@ -181,10 +204,10 @@ class Vmtp(singlevm.VmReady2):
def clean(self):
try:
assert self.cloud
- super(Vmtp, self).clean()
+ super().clean()
os.remove(self.privkey_filename)
os.remove(self.pubkey_filename)
- self.cloud.delete_network("pns-internal-net_{}".format(self.guid))
- self.cloud.delete_network("pns-internal-net2_{}".format(self.guid))
+ self.cloud.delete_network(f"pns-internal-net_{self.guid}")
+ self.cloud.delete_network(f"pns-internal-net2_{self.guid}")
except Exception: # pylint: disable=broad-except
pass
diff --git a/functest/opnfv_tests/openstack/vping/vping_ssh.py b/functest/opnfv_tests/openstack/vping/vping_ssh.py
index 6420013a0..ad64348c4 100644
--- a/functest/opnfv_tests/openstack/vping/vping_ssh.py
+++ b/functest/opnfv_tests/openstack/vping/vping_ssh.py
@@ -29,13 +29,13 @@ class VPingSSH(singlevm.SingleVm2):
"""Initialize testcase."""
if "case_name" not in kwargs:
kwargs["case_name"] = "vping_ssh"
- super(VPingSSH, self).__init__(**kwargs)
+ super().__init__(**kwargs)
self.vm2 = None
def prepare(self):
- super(VPingSSH, self).prepare()
+ super().prepare()
self.vm2 = self.boot_vm(
- '{}-vm2_{}'.format(self.case_name, self.guid),
+ f'{self.case_name}-vm2_{self.guid}',
security_groups=[self.sec.id])
def execute(self):
@@ -44,12 +44,13 @@ class VPingSSH(singlevm.SingleVm2):
Returns: ping exit codes
"""
assert self.ssh
- (_, stdout, stderr) = self.ssh.exec_command(
- 'ping -c 1 {}'.format(
- self.vm2.private_v4 or self.vm2.addresses[
- self.network.name][0].addr))
- self.__logger.info("output:\n%s", stdout.read())
- self.__logger.info("error:\n%s", stderr.read())
+ if not self.check_regex_in_console(self.vm2.name):
+ return 1
+ ip4 = self.vm2.private_v4 or self.vm2.addresses[
+ self.network.name][0].addr
+ (_, stdout, stderr) = self.ssh.exec_command(f'ping -c 1 {ip4}')
+ self.__logger.info("output:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.info("error:\n%s", stderr.read().decode("utf-8"))
return stdout.channel.recv_exit_status()
def clean(self):
@@ -58,4 +59,4 @@ class VPingSSH(singlevm.SingleVm2):
self.cloud.delete_server(
self.vm2, wait=True,
timeout=getattr(config.CONF, 'vping_vm_delete_timeout'))
- super(VPingSSH, self).clean()
+ super().clean()
diff --git a/functest/opnfv_tests/openstack/vping/vping_userdata.py b/functest/opnfv_tests/openstack/vping/vping_userdata.py
index a58184c59..8a8f26f37 100644
--- a/functest/opnfv_tests/openstack/vping/vping_userdata.py
+++ b/functest/opnfv_tests/openstack/vping/vping_userdata.py
@@ -26,7 +26,7 @@ class VPingUserdata(singlevm.VmReady2):
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = "vping_userdata"
- super(VPingUserdata, self).__init__(**kwargs)
+ super().__init__(**kwargs)
self.logger = logging.getLogger(__name__)
self.vm1 = None
self.vm2 = None
@@ -39,12 +39,12 @@ class VPingUserdata(singlevm.VmReady2):
"""
try:
assert self.cloud
- assert super(VPingUserdata, self).run(
+ assert super().run(
**kwargs) == testcase.TestCase.EX_OK
self.result = 0
self.vm1 = self.boot_vm()
self.vm2 = self.boot_vm(
- '{}-vm2_{}'.format(self.case_name, self.guid),
+ f'{self.case_name}-vm2_{self.guid}',
userdata=self._get_userdata())
result = self._do_vping()
@@ -79,16 +79,16 @@ class VPingUserdata(singlevm.VmReady2):
self.logger.info("vPing detected!")
exit_code = testcase.TestCase.EX_OK
break
- elif "failed to read iid from metadata" in p_console or tries > 5:
+ if "failed to read iid from metadata" in p_console or tries > 5:
self.logger.info("Failed to read iid from metadata")
break
- elif sec == getattr(config.CONF, 'vping_ping_timeout'):
+ if sec == getattr(config.CONF, 'vping_ping_timeout'):
self.logger.info("Timeout reached.")
break
- elif sec % 10 == 0:
+ if sec % 10 == 0:
if "request failed" in p_console:
self.logger.debug(
- "It seems userdata is not supported in nova boot. " +
+ "It seems userdata is not supported in nova boot. "
"Waiting a bit...")
tries += 1
else:
@@ -104,13 +104,15 @@ class VPingUserdata(singlevm.VmReady2):
"""
Returns the post VM creation script to be added into the VM's userdata
:param test_ip: the IP value to substitute into the script
- :return: the bash script contents
+ :return: the shell script contents
"""
+ ip4 = self.vm1.private_v4 or self.vm1.addresses[
+ self.network.name][0].addr
if self.vm1.private_v4 or self.vm1.addresses[
self.network.name][0].addr:
return ("#!/bin/sh\n\n"
"while true; do\n"
- " ping -c 1 %s 2>&1 >/dev/null\n"
+ f" ping -c 1 {ip4} 2>&1 >/dev/null\n"
" RES=$?\n"
" if [ \"Z$RES\" = \"Z0\" ] ; then\n"
" echo 'vPing OK'\n"
@@ -119,9 +121,7 @@ class VPingUserdata(singlevm.VmReady2):
" echo 'vPing KO'\n"
" fi\n"
" sleep 1\n"
- "done\n" % str(
- self.vm1.private_v4 or self.vm1.addresses[
- self.network.name][0].addr))
+ "done\n")
return None
def clean(self):
@@ -134,4 +134,4 @@ class VPingUserdata(singlevm.VmReady2):
self.cloud.delete_server(
self.vm2, wait=True,
timeout=getattr(config.CONF, 'vping_vm_delete_timeout'))
- super(VPingUserdata, self).clean()
+ super().clean()
diff --git a/functest/opnfv_tests/sdn/odl/odl.py b/functest/opnfv_tests/sdn/odl/odl.py
index 17600a316..72c38ce2c 100644
--- a/functest/opnfv_tests/sdn/odl/odl.py
+++ b/functest/opnfv_tests/sdn/odl/odl.py
@@ -49,7 +49,7 @@ class ODLTests(robotframework.RobotFramework):
__logger = logging.getLogger(__name__)
def __init__(self, **kwargs):
- super(ODLTests, self).__init__(**kwargs)
+ super().__init__(**kwargs)
self.res_dir = os.path.join(
getattr(config.CONF, 'dir_results'), 'odl')
self.xml_file = os.path.join(self.res_dir, 'output.xml')
@@ -66,10 +66,10 @@ class ODLTests(robotframework.RobotFramework):
try:
for line in fileinput.input(cls.odl_variables_file,
inplace=True):
- print(re.sub("@{AUTH}.*",
- "@{{AUTH}} {} {}".format(
- odlusername, odlpassword),
- line.rstrip()))
+ print(re.sub(
+ "@{AUTH}.*",
+ f"@{{AUTH}} {odlusername} {odlpassword}",
+ line.rstrip()))
return True
except Exception: # pylint: disable=broad-except
cls.__logger.exception("Cannot set ODL creds:")
@@ -111,9 +111,8 @@ class ODLTests(robotframework.RobotFramework):
odlusername = kwargs['odlusername']
odlpassword = kwargs['odlpassword']
osauthurl = kwargs['osauthurl']
- keystoneurl = "{}://{}".format(
- urllib.parse.urlparse(osauthurl).scheme,
- urllib.parse.urlparse(osauthurl).netloc)
+ keystoneurl = (f"{urllib.parse.urlparse(osauthurl).scheme}://"
+ f"{urllib.parse.urlparse(osauthurl).netloc}")
variable = ['KEYSTONEURL:' + keystoneurl,
'NEUTRONURL:' + kwargs['neutronurl'],
'OS_AUTH_URL:"' + osauthurl + '"',
@@ -135,7 +134,7 @@ class ODLTests(robotframework.RobotFramework):
else:
if not self.set_robotframework_vars(odlusername, odlpassword):
return self.EX_RUN_ERROR
- return super(ODLTests, self).run(variable=variable, suites=suites)
+ return super().run(variable=variable, suites=suites)
def run(self, **kwargs):
"""Run suites in OPNFV environment
@@ -189,7 +188,7 @@ class ODLTests(robotframework.RobotFramework):
return self.run_suites(suites, **kwargs)
-class ODLParser(object): # pylint: disable=too-few-public-methods
+class ODLParser(): # pylint: disable=too-few-public-methods
"""Parser to run ODL test suites."""
def __init__(self):
diff --git a/functest/opnfv_tests/vnf/epc/juju_epc.py b/functest/opnfv_tests/vnf/epc/juju_epc.py
index 644911bd7..1cf240b80 100644
--- a/functest/opnfv_tests/vnf/epc/juju_epc.py
+++ b/functest/opnfv_tests/vnf/epc/juju_epc.py
@@ -14,17 +14,16 @@ import os
import time
import json
import re
-import subprocess
import sys
from copy import deepcopy
import pkg_resources
-import six
-import yaml
+import scp
from functest.core import singlevm
from functest.utils import config
from functest.utils import env
+from functest.utils import functest_utils
__author__ = "Amarendra Meher <amarendra@rebaca.com>"
__author__ = "Soumaya K Nayek <soumaya.nayek@rebaca.com>"
@@ -43,7 +42,7 @@ CREDS_TEMPLATE2 = """credentials:
default-credential: abot-epc
abot-epc:
auth-type: userpass
- password: {pass}
+ password: '{pass}'
project-domain-name: {project_domain_n}
tenant-name: {tenant_n}"""
@@ -52,20 +51,20 @@ CREDS_TEMPLATE = """credentials:
default-credential: abot-epc
abot-epc:
auth-type: userpass
- password: {pass}
+ password: '{pass}'
project-domain-name: {project_domain_n}
tenant-name: {tenant_n}
user-domain-name: {user_domain_n}
username: {user_n}"""
-class JujuEpc(singlevm.VmReady2):
+class JujuEpc(singlevm.SingleVm2):
# pylint:disable=too-many-instance-attributes
"""Abot EPC deployed with JUJU Orchestrator Case"""
__logger = logging.getLogger(__name__)
- cidr = '192.168.121.0/24'
+ cidr = '192.168.120.0/24'
filename = ('/home/opnfv/functest/images/'
'ubuntu-16.04-server-cloudimg-amd64-disk1.img')
@@ -75,53 +74,62 @@ class JujuEpc(singlevm.VmReady2):
flavor_ram = 2048
flavor_vcpus = 1
flavor_disk = 10
-
flavor_alt_ram = 4096
flavor_alt_vcpus = 1
flavor_alt_disk = 10
-
- juju_timeout = '3600'
+ username = 'ubuntu'
+ juju_timeout = '4800'
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = "juju_epc"
- super(JujuEpc, self).__init__(**kwargs)
+ super().__init__(**kwargs)
# Retrieve the configuration
self.case_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/vnf/epc')
try:
self.config = getattr(
- config.CONF, 'vnf_{}_config'.format(self.case_name))
- except Exception:
- raise Exception("VNF config file not found")
+ config.CONF, f'vnf_{self.case_name}_config')
+ except Exception as exc:
+ raise Exception("VNF config file not found") from exc
self.config_file = os.path.join(self.case_dir, self.config)
- self.orchestrator = dict(requirements=get_config(
- "orchestrator.requirements", self.config_file))
+ self.orchestrator = dict(
+ requirements=functest_utils.get_parameter_from_yaml(
+ "orchestrator.requirements", self.config_file))
self.created_object = []
self.details['orchestrator'] = dict(
- name=get_config("orchestrator.name", self.config_file),
- version=get_config("orchestrator.version", self.config_file),
+ name=functest_utils.get_parameter_from_yaml(
+ "orchestrator.name", self.config_file),
+ version=functest_utils.get_parameter_from_yaml(
+ "orchestrator.version", self.config_file),
status='ERROR',
result=''
)
self.vnf = dict(
- descriptor=get_config("vnf.descriptor", self.config_file),
- requirements=get_config("vnf.requirements", self.config_file)
+ descriptor=functest_utils.get_parameter_from_yaml(
+ "vnf.descriptor", self.config_file),
+ requirements=functest_utils.get_parameter_from_yaml(
+ "vnf.requirements", self.config_file)
)
self.details['vnf'] = dict(
descriptor_version=self.vnf['descriptor']['version'],
- name=get_config("vnf.name", self.config_file),
- version=get_config("vnf.version", self.config_file),
+ name=functest_utils.get_parameter_from_yaml(
+ "vnf.name", self.config_file),
+ version=functest_utils.get_parameter_from_yaml(
+ "vnf.version", self.config_file),
)
self.__logger.debug("VNF configuration: %s", self.vnf)
self.details['test_vnf'] = dict(
- name=get_config("vnf_test_suite.name", self.config_file),
- version=get_config("vnf_test_suite.version", self.config_file),
- tag_name=get_config("vnf_test_suite.tag_name", self.config_file)
+ name=functest_utils.get_parameter_from_yaml(
+ "vnf_test_suite.name", self.config_file),
+ version=functest_utils.get_parameter_from_yaml(
+ "vnf_test_suite.version", self.config_file),
+ tag_name=functest_utils.get_parameter_from_yaml(
+ "vnf_test_suite.tag_name", self.config_file)
)
self.res_dir = os.path.join(
@@ -130,20 +138,27 @@ class JujuEpc(singlevm.VmReady2):
try:
self.public_auth_url = self.get_public_auth_url(self.orig_cloud)
if not self.public_auth_url.endswith(('v3', 'v3/')):
- self.public_auth_url = six.moves.urllib.parse.urljoin(
- self.public_auth_url, 'v3')
+ self.public_auth_url = f"{self.public_auth_url}/v3"
except Exception: # pylint: disable=broad-except
self.public_auth_url = None
self.sec = None
self.image_alt = None
self.flavor_alt = None
- def check_requirements(self):
- if env.get('NEW_USER_ROLE').lower() == "admin":
- self.__logger.warn(
- "Defining NEW_USER_ROLE=admin will easily break the testcase "
- "because Juju doesn't manage tenancy (e.g. subnet "
- "overlapping)")
+ def _install_juju(self):
+ (_, stdout, stderr) = self.ssh.exec_command(
+ 'sudo snap install juju --channel=2.3/stable --classic')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ return not stdout.channel.recv_exit_status()
+
+ def _install_juju_wait(self):
+ (_, stdout, stderr) = self.ssh.exec_command(
+ 'sudo apt-get update && sudo apt-get install python3-pip -y && '
+ 'sudo pip3 install juju_wait===2.6.4')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ return not stdout.channel.recv_exit_status()
def _register_cloud(self):
assert self.public_auth_url
@@ -153,11 +168,15 @@ class JujuEpc(singlevm.VmReady2):
'url': self.public_auth_url,
'region': self.cloud.region_name if self.cloud.region_name else (
'RegionOne')}
- with open(clouds_yaml, 'w') as yfile:
+ with open(clouds_yaml, 'w', encoding='utf-8') as yfile:
yfile.write(CLOUD_TEMPLATE.format(**cloud_data))
- cmd = ['juju', 'add-cloud', 'abot-epc', '-f', clouds_yaml, '--replace']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
+ scpc = scp.SCPClient(self.ssh.get_transport())
+ scpc.put(clouds_yaml, remote_path='~/')
+ (_, stdout, stderr) = self.ssh.exec_command(
+ '/snap/bin/juju add-cloud abot-epc -f clouds.yaml --replace')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ return not stdout.channel.recv_exit_status()
def _register_credentials(self):
self.__logger.info("Creating Credentials for Abot-epc .....")
@@ -170,48 +189,38 @@ class JujuEpc(singlevm.VmReady2):
"project_domain_name", "Default"),
'user_domain_n': self.cloud.auth.get(
"user_domain_name", "Default")}
- with open(credentials_yaml, 'w') as yfile:
+ with open(credentials_yaml, 'w', encoding='utf-8') as yfile:
yfile.write(CREDS_TEMPLATE.format(**creds_data))
- cmd = ['juju', 'add-credential', 'abot-epc', '-f', credentials_yaml,
- '--replace']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
-
- def prepare(self):
- """Prepare testcase (Additional pre-configuration steps)."""
- assert self.public_auth_url
- self.__logger.info("Additional pre-configuration steps")
- try:
- os.makedirs(self.res_dir)
- except OSError as ex:
- if ex.errno != errno.EEXIST:
- self.__logger.exception("Cannot create %s", self.res_dir)
- raise Exception
-
- self.__logger.info("ENV:\n%s", env.string())
- self._register_cloud()
- self._register_credentials()
-
- def publish_image(self, name=None):
- image = super(JujuEpc, self).publish_image(name)
- cmd = ['juju', 'metadata', 'generate-image', '-d', '/root',
- '-i', image.id, '-s', 'xenial',
- '-r', self.cloud.region_name if self.cloud.region_name else (
- 'RegionOne'),
- '-u', self.public_auth_url]
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
- return image
+ scpc = scp.SCPClient(self.ssh.get_transport())
+ scpc.put(credentials_yaml, remote_path='~/')
+ (_, stdout, stderr) = self.ssh.exec_command(
+ '/snap/bin/juju add-credential abot-epc -f credentials.yaml '
+ ' --replace --debug')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ return not stdout.channel.recv_exit_status()
+
+ def _publish_image(self):
+ region_name = self.cloud.region_name if self.cloud.region_name else (
+ 'RegionOne')
+ (_, stdout, stderr) = self.ssh.exec_command(
+ '/snap/bin/juju metadata generate-image -d /home/ubuntu '
+ f'-i {self.image.id} -s xenial -r {region_name} '
+ f'-u {self.public_auth_url}')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ return not stdout.channel.recv_exit_status()
def publish_image_alt(self, name=None):
- image_alt = super(JujuEpc, self).publish_image_alt(name)
- cmd = ['juju', 'metadata', 'generate-image', '-d', '/root',
- '-i', image_alt.id, '-s', 'trusty',
- '-r', self.cloud.region_name if self.cloud.region_name else (
- 'RegionOne'),
- '-u', self.public_auth_url]
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
+ image_alt = super().publish_image_alt(name)
+ region_name = self.cloud.region_name if self.cloud.region_name else (
+ 'RegionOne')
+ (_, stdout, stderr) = self.ssh.exec_command(
+ '/snap/bin/juju metadata generate-image -d /home/ubuntu '
+ f'-i {image_alt.id} -s trusty -r {region_name} '
+ f'-u {self.public_auth_url}')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
return image_alt
def deploy_orchestrator(self): # pylint: disable=too-many-locals
@@ -220,122 +229,128 @@ class JujuEpc(singlevm.VmReady2):
Bootstrap juju
"""
+ self._publish_image()
self.image_alt = self.publish_image_alt()
self.flavor_alt = self.create_flavor_alt()
self.__logger.info("Starting Juju Bootstrap process...")
- try:
- cmd = ['timeout', '-t', JujuEpc.juju_timeout,
- 'juju', 'bootstrap',
- 'abot-epc/{}'.format(
- self.cloud.region_name if self.cloud.region_name else (
- 'RegionOne')),
- 'abot-controller',
- '--agent-version', '2.3.9',
- '--metadata-source', '/root',
- '--constraints', 'mem=2G',
- '--bootstrap-series', 'xenial',
- '--config', 'network={}'.format(self.network.id),
- '--config', 'ssl-hostname-verification=false',
- '--config', 'use-floating-ip=true',
- '--config', 'use-default-secgroup=true',
- '--debug']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
- except subprocess.CalledProcessError as cpe:
- self.__logger.error(
- "Exception with Juju Bootstrap: %s\n%s",
- cpe.cmd, cpe.output)
- return False
- except Exception: # pylint: disable=broad-except
- self.__logger.exception("Some issue with Juju Bootstrap ...")
- return False
-
- return True
+ region_name = self.cloud.region_name if self.cloud.region_name else (
+ 'RegionOne')
+ (_, stdout, stderr) = self.ssh.exec_command(
+ f'timeout {JujuEpc.juju_timeout} '
+ f'/snap/bin/juju bootstrap abot-epc/{region_name} abot-controller '
+ '--agent-version 2.3.9 --metadata-source /home/ubuntu '
+ '--constraints mem=2G --bootstrap-series xenial '
+ f'--config network={self.network.id} '
+ '--config ssl-hostname-verification=false '
+ f'--config external-network={self.ext_net.id} '
+ '--config use-floating-ip=true '
+ '--config use-default-secgroup=true '
+ '--debug')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ return not stdout.channel.recv_exit_status()
def check_app(self, name='abot-epc-basic', status='active'):
"""Check application status."""
- cmd = ['juju', 'status', '--format', 'short', name]
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
- ret = re.search(r'(?=workload:({})\))'.format(status), output)
- if ret:
- self.__logger.info("%s workload is %s", name, status)
- return True
- self.__logger.error("%s workload differs from %s", name, status)
- return False
+ for i in range(10):
+ (_, stdout, stderr) = self.ssh.exec_command(
+ f'/snap/bin/juju status --format short {name}')
+ output = stdout.read().decode("utf-8")
+ self.__logger.debug("stdout:\n%s", output)
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ if stdout.channel.recv_exit_status():
+ continue
+ ret = re.search(
+ rf'(?=workload:({status})\))', output)
+ if ret:
+ self.__logger.info("%s workload is %s", name, status)
+ break
+ self.__logger.info(
+ "loop %d: %s workload differs from %s", i + 1, name, status)
+ time.sleep(60)
+ else:
+ self.__logger.error("%s workload differs from %s", name, status)
+ return False
+ return True
def deploy_vnf(self):
"""Deploy ABOT-OAI-EPC."""
self.__logger.info("Upload VNFD")
- descriptor = self.vnf['descriptor']
+ scpc = scp.SCPClient(self.ssh.get_transport())
+ scpc.put(
+ '/src/epc-requirements/abot_charm', remote_path='~/',
+ recursive=True)
self.__logger.info("Deploying Abot-epc bundle file ...")
- cmd = ['juju', 'deploy', '{}'.format(descriptor.get('file_name'))]
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
- self.__logger.info("Waiting for instances .....")
- try:
- cmd = ['timeout', '-t', JujuEpc.juju_timeout, 'juju-wait']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
- self.__logger.info("Deployed Abot-epc on Openstack")
- except subprocess.CalledProcessError as cpe:
- self.__logger.error(
- "Exception with Juju VNF Deployment: %s\n%s",
- cpe.cmd, cpe.output)
- return False
- except Exception: # pylint: disable=broad-except
- self.__logger.exception("Some issue with the VNF Deployment ..")
- return False
-
+ (_, stdout, stderr) = self.ssh.exec_command(
+ 'sudo mkdir -p /src/epc-requirements && '
+ 'sudo mv abot_charm /src/epc-requirements/abot_charm && '
+ '/snap/bin/juju deploy '
+ '/src/epc-requirements/abot_charm/functest-abot-epc-bundle/'
+ 'bundle.yaml')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ if stdout.channel.recv_exit_status():
+ return not stdout.channel.recv_exit_status()
+ (_, stdout, stderr) = self.ssh.exec_command(
+ 'PATH=/snap/bin/:$PATH '
+ f'timeout {JujuEpc.juju_timeout} juju-wait')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ if stdout.channel.recv_exit_status():
+ return not stdout.channel.recv_exit_status()
self.__logger.info("Checking status of ABot and EPC units ...")
- cmd = ['juju', 'status']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.debug("%s\n%s", " ".join(cmd), output)
+ (_, stdout, stderr) = self.ssh.exec_command('/snap/bin/juju status')
+ output = stdout.read().decode("utf-8")
+ self.__logger.debug("stdout:\n%s", output)
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ if stdout.channel.recv_exit_status():
+ return not stdout.channel.recv_exit_status()
for app in ['abot-epc-basic', 'oai-epc', 'oai-hss']:
if not self.check_app(app):
return False
-
- self.__logger.info("Transferring the feature files to Abot_node ...")
- cmd = ['timeout', '-t', JujuEpc.juju_timeout,
- 'juju', 'scp', '--', '-r', '-v',
- '{}/featureFiles'.format(self.case_dir), 'abot-epc-basic/0:~/']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
-
- self.__logger.info("Copying the feature files within Abot_node ")
- cmd = ['timeout', '-t', JujuEpc.juju_timeout,
- 'juju', 'ssh', 'abot-epc-basic/0',
- 'sudo', 'cp', '-vfR', '~/featureFiles/*',
- '/etc/rebaca-test-suite/featureFiles']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
- return True
+ scpc = scp.SCPClient(self.ssh.get_transport())
+ scpc.put(
+ f'{self.case_dir}/featureFiles', remote_path='~/',
+ recursive=True)
+ (_, stdout, stderr) = self.ssh.exec_command(
+ f'timeout {JujuEpc.juju_timeout} /snap/bin/juju scp -- -r -v '
+ '~/featureFiles abot-epc-basic/0:/etc/rebaca-test-suite/')
+ output = stdout.read().decode("utf-8")
+ self.__logger.debug("stdout:\n%s", output)
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ return not stdout.channel.recv_exit_status()
def test_vnf(self):
"""Run test on ABoT."""
start_time = time.time()
- self.__logger.info("Running VNF Test cases....")
- cmd = ['juju', 'run-action', 'abot-epc-basic/0', 'run',
- 'tagnames={}'.format(self.details['test_vnf']['tag_name'])]
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
-
- cmd = ['timeout', '-t', JujuEpc.juju_timeout, 'juju-wait']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
-
+ (_, stdout, stderr) = self.ssh.exec_command(
+ "/snap/bin/juju run-action abot-epc-basic/0 "
+ f"run tagnames={self.details['test_vnf']['tag_name']}")
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ if stdout.channel.recv_exit_status():
+ return not stdout.channel.recv_exit_status()
+ (_, stdout, stderr) = self.ssh.exec_command(
+ 'PATH=/snap/bin/:$PATH '
+ f'timeout {JujuEpc.juju_timeout} juju-wait')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ if stdout.channel.recv_exit_status():
+ return not stdout.channel.recv_exit_status()
duration = time.time() - start_time
self.__logger.info("Getting results from Abot node....")
- cmd = ['timeout', '-t', JujuEpc.juju_timeout,
- 'juju', 'scp', '--', '-v',
- 'abot-epc-basic/0:'
- '/var/lib/abot-epc-basic/artifacts/TestResults.json',
- '{}/.'.format(self.res_dir)]
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
+ (_, stdout, stderr) = self.ssh.exec_command(
+ f'timeout {JujuEpc.juju_timeout} /snap/bin/juju scp '
+ '-- -v abot-epc-basic/0:'
+ '/var/lib/abot-epc-basic/artifacts/TestResults.json .')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ if stdout.channel.recv_exit_status():
+ return not stdout.channel.recv_exit_status()
+ scpc = scp.SCPClient(self.ssh.get_transport())
+ scpc.get('TestResults.json', self.res_dir)
self.__logger.info("Parsing the Test results...")
- res = (process_abot_test_result('{}/TestResults.json'.format(
- self.res_dir)))
+ res = process_abot_test_result(f'{self.res_dir}/TestResults.json')
short_result = sig_test_format(res)
self.__logger.info(short_result)
self.details['test_vnf'].update(
@@ -347,73 +362,48 @@ class JujuEpc(singlevm.VmReady2):
short_result['failures'], short_result['skipped'])
return True
- def run(self, **kwargs):
- self.start_time = time.time()
+ def execute(self):
+ """Prepare testcase (Additional pre-configuration steps)."""
+ assert self.public_auth_url
+ self.__logger.info("Additional pre-configuration steps")
try:
- assert super(JujuEpc, self).run(**kwargs) == self.EX_OK
- self.prepare()
- if (self.deploy_orchestrator() and
- self.deploy_vnf() and
- self.test_vnf()):
- self.stop_time = time.time()
- self.result = 100
- return self.EX_OK
- self.result = 0
- self.stop_time = time.time()
- return self.EX_TESTCASE_FAILED
+ os.makedirs(self.res_dir)
+ except OSError as ex:
+ if ex.errno != errno.EEXIST:
+ self.__logger.exception("Cannot create %s", self.res_dir)
+ raise Exception from ex
+ self.__logger.info("ENV:\n%s", env.string())
+ try:
+ assert self._install_juju()
+ assert self._install_juju_wait()
+ assert self._register_cloud()
+ assert self._register_credentials()
+ assert self.deploy_orchestrator()
+ assert self.deploy_vnf()
+ assert self.test_vnf()
except Exception: # pylint: disable=broad-except
- self.stop_time = time.time()
- self.__logger.exception("Exception on VNF testing")
- return self.EX_TESTCASE_FAILED
+ self.__logger.exception("juju_epc failed")
+ return 1
+ return 0
def clean(self):
"""Clean created objects/functions."""
- try:
- cmd = ['juju', 'debug-log', '--replay', '--no-tail']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.debug("%s\n%s", " ".join(cmd), output)
- self.__logger.info("Destroying Orchestrator...")
- cmd = ['timeout', '-t', JujuEpc.juju_timeout,
- 'juju', 'destroy-controller', '-y', 'abot-controller',
- '--destroy-all-models']
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- self.__logger.info("%s\n%s", " ".join(cmd), output)
- except subprocess.CalledProcessError as cpe:
- self.__logger.error(
- "Exception with Juju Cleanup: %s\n%s",
- cpe.cmd, cpe.output)
- except Exception: # pylint: disable=broad-except
- self.__logger.exception("General issue during the undeployment ..")
+ (_, stdout, stderr) = self.ssh.exec_command(
+ '/snap/bin/juju debug-log --replay --no-tail')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
+ (_, stdout, stderr) = self.ssh.exec_command(
+ '/snap/bin/juju destroy-controller -y abot-controller '
+ '--destroy-all-models')
+ self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8"))
+ self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8"))
for fip in self.cloud.list_floating_ips():
self.cloud.delete_floating_ip(fip.id)
if self.image_alt:
self.cloud.delete_image(self.image_alt)
if self.flavor_alt:
self.orig_cloud.delete_flavor(self.flavor_alt.id)
- super(JujuEpc, self).clean()
-
-
-# ----------------------------------------------------------
-#
-# YAML UTILS
-#
-# -----------------------------------------------------------
-def get_config(parameter, file_path):
- """
- Returns the value of a given parameter in file.yaml
- parameter must be given in string format with dots
- Example: general.openstack.image_name
- """
- with open(file_path) as config_file:
- file_yaml = yaml.safe_load(config_file)
- config_file.close()
- value = file_yaml
- for element in parameter.split("."):
- value = value.get(element)
- if value is None:
- raise ValueError("The parameter %s is not defined in"
- " reporting.yaml" % parameter)
- return value
+ super().clean()
def sig_test_format(sig_test):
@@ -439,7 +429,7 @@ def sig_test_format(sig_test):
def process_abot_test_result(file_path):
""" Process ABoT Result """
- with open(file_path) as test_result:
+ with open(file_path, encoding='utf-8') as test_result:
data = json.load(test_result)
res = []
for tests in data:
diff --git a/functest/opnfv_tests/vnf/ims/clearwater.py b/functest/opnfv_tests/vnf/ims/clearwater.py
index 57857b563..4c143fd70 100644
--- a/functest/opnfv_tests/vnf/ims/clearwater.py
+++ b/functest/opnfv_tests/vnf/ims/clearwater.py
@@ -12,9 +12,6 @@
import logging
import os
import re
-import shlex
-import shutil
-import subprocess
import time
import pkg_resources
@@ -27,10 +24,10 @@ __author__ = ("Valentin Boucher <valentin.boucher@orange.com>, "
"Helen Yao <helanyao@gmail.com>")
-class ClearwaterTesting(object):
+class ClearwaterTesting():
"""vIMS clearwater base usable by several orchestrators"""
- def __init__(self, case_name, ellis_ip):
+ def __init__(self, case_name, bono_ip, ellis_ip):
self.logger = logging.getLogger(__name__)
self.case_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/vnf/ims')
@@ -45,16 +42,15 @@ class ClearwaterTesting(object):
os.makedirs(self.result_dir)
self.ellis_ip = ellis_ip
+ self.bono_ip = bono_ip
- def availability_check_by_creating_numbers(self,
- signup_code='secret',
- two_numbers=False):
+ def availability_check(self, signup_code='secret', two_numbers=False):
"""Create one or two numbers"""
assert self.ellis_ip
output_dict = {}
self.logger.debug('Ellis IP: %s', self.ellis_ip)
output_dict['ellis_ip'] = self.ellis_ip
- account_url = 'http://{0}/accounts'.format(self.ellis_ip)
+ account_url = f'http://{self.ellis_ip}/accounts'
params = {"password": "functest",
"full_name": "opnfv functest user",
"email": "functest@opnfv.org",
@@ -64,7 +60,7 @@ class ClearwaterTesting(object):
number_res = self._create_ellis_account(account_url, params)
output_dict['number'] = number_res
- session_url = 'http://{0}/session'.format(self.ellis_ip)
+ session_url = f'http://{self.ellis_ip}/session'
session_data = {
'username': params['email'],
'password': params['password'],
@@ -72,8 +68,8 @@ class ClearwaterTesting(object):
}
cookies = self._get_ellis_session_cookies(session_url, session_data)
- number_url = 'http://{0}/accounts/{1}/numbers'.format(
- self.ellis_ip, params['email'])
+ number_url = (
+ f"http://{self.ellis_ip}/accounts/{params['email']}/numbers")
self.logger.debug('Create 1st calling number on Ellis')
number_res = self._create_ellis_number(number_url, cookies)
@@ -85,7 +81,7 @@ class ClearwaterTesting(object):
return output_dict
def _create_ellis_account(self, account_url, params):
- i = 50
+ i = 80
for iloop in range(i):
try:
req = requests.post(account_url, data=params)
@@ -95,15 +91,13 @@ class ClearwaterTesting(object):
'Account %s is created on Ellis\n%s',
params.get('full_name'), account_res)
return account_res
- else:
- raise Exception("Cannot create ellis account")
+ raise Exception("Cannot create ellis account")
except Exception: # pylint: disable=broad-except
self.logger.info(
"try %s: cannot create ellis account", iloop + 1)
- time.sleep(25)
+ time.sleep(30)
raise Exception(
- "Unable to create an account {}".format(
- params.get('full_name')))
+ f"Unable to create an account {params.get('full_name')}")
def _get_ellis_session_cookies(self, session_url, params):
i = 15
@@ -114,8 +108,7 @@ class ClearwaterTesting(object):
cookies = req.cookies
self.logger.debug('cookies: %s', cookies)
return cookies
- else:
- raise Exception('Failed to get cookies for Ellis')
+ raise Exception('Failed to get cookies for Ellis')
except Exception: # pylint: disable=broad-except
self.logger.info(
"try %s: cannot get cookies for Ellis", iloop + 1)
@@ -132,22 +125,19 @@ class ClearwaterTesting(object):
self.logger.info(
'Calling number is created: %s', number_res)
return number_res
+ if req and req.json():
+ reason = req.json()['reason']
else:
- if req and req.json():
- reason = req.json()['reason']
- else:
- reason = req
- self.logger.info("cannot create a number: %s", reason)
- raise Exception('Failed to create a number')
+ reason = req
+ self.logger.info("cannot create a number: %s", reason)
+ raise Exception('Failed to create a number')
except Exception: # pylint: disable=broad-except
self.logger.info(
"try %s: cannot create a number", iloop + 1)
time.sleep(25)
raise Exception('Failed to create a number')
- def run_clearwater_live_test(self, dns_ip, public_domain,
- bono_ip=None, ellis_ip=None,
- signup_code='secret'):
+ def run_clearwater_live_test(self, public_domain, signup_code='secret'):
"""Run the Clearwater live tests
It first runs dnsmasq to reach clearwater services by FQDN and then the
@@ -159,38 +149,20 @@ class ClearwaterTesting(object):
"""
# pylint: disable=too-many-locals,too-many-arguments
self.logger.info('Run Clearwater live test')
- dns_file = '/etc/resolv.conf'
- dns_file_bak = '/etc/resolv.conf.bak'
- self.logger.debug('Backup %s -> %s', dns_file, dns_file_bak)
- shutil.copy(dns_file, dns_file_bak)
- cmd = ("dnsmasq -d -u root --server=/clearwater.opnfv/{0} "
- "-r /etc/resolv.conf.bak".format(dns_ip))
- dnsmasq_process = subprocess.Popen(shlex.split(cmd))
- script = ('echo -e "nameserver {0}" > {1};'
- 'cd {2};'
- 'rake test[{3}] SIGNUP_CODE={4}'
- .format('127.0.0.1',
- dns_file,
- self.test_dir,
- public_domain,
- signup_code))
- if bono_ip and ellis_ip:
- subscript = ' PROXY={0} ELLIS={1}'.format(bono_ip, ellis_ip)
- script = '{0}{1}'.format(script, subscript)
- script = ('{0}{1}'.format(script, ' --trace'))
- cmd = "/bin/bash -c '{0}'".format(script)
+ script = (f'cd {self.test_dir};'
+ f'rake test[{public_domain}] SIGNUP_CODE={signup_code}')
+ if self.bono_ip and self.ellis_ip:
+ subscript = f' PROXY={self.bono_ip} ELLIS={self.ellis_ip}'
+ script = f'{script}{subscript}'
+ script = f'{script} --trace'
+ cmd = f"/bin/sh -c '{script}'"
self.logger.debug('Live test cmd: %s', cmd)
output_file = os.path.join(self.result_dir, "ims_test_output.txt")
ft_utils.execute_command(cmd,
error_msg='Clearwater live test failed',
output_file=output_file)
- dnsmasq_process.kill()
- with open(dns_file_bak, 'r') as bak_file:
- result = bak_file.read()
- with open(dns_file, 'w') as dfile:
- dfile.write(result)
- with open(output_file, 'r') as ofile:
+ with open(output_file, 'r', encoding='utf-8') as ofile:
result = ofile.read()
if result != "":
@@ -207,7 +179,12 @@ class ClearwaterTesting(object):
vims_test_result["skipped"] = int(grp.group(3))
vims_test_result['passed'] = (
int(grp.group(2)) - int(grp.group(3)) - int(grp.group(1)))
+ if vims_test_result['total'] - vims_test_result['skipped'] > 0:
+ vnf_test_rate = vims_test_result['passed'] / (
+ vims_test_result['total'] - vims_test_result['skipped'])
+ else:
+ vnf_test_rate = 0
except Exception: # pylint: disable=broad-except
self.logger.exception("Cannot parse live tests results")
- return None
- return vims_test_result
+ return None, 0
+ return vims_test_result, vnf_test_rate
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
index 08699e4bb..b93af7d6d 100644
--- a/functest/opnfv_tests/vnf/ims/cloudify_ims.py
+++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
@@ -14,17 +14,15 @@ from __future__ import division
import logging
import os
import time
-import yaml
-from cloudify_rest_client.executions import Execution
import pkg_resources
-import scp
import six
from functest.core import cloudify
from functest.opnfv_tests.vnf.ims import clearwater
from functest.utils import config
from functest.utils import env
+from functest.utils import functest_utils
__author__ = "Valentin Boucher <valentin.boucher@orange.com>"
@@ -37,52 +35,66 @@ class CloudifyIms(cloudify.Cloudify):
filename_alt = ('/home/opnfv/functest/images/'
'ubuntu-14.04-server-cloudimg-amd64-disk1.img')
- flavor_alt_ram = 2048
- flavor_alt_vcpus = 2
- flavor_alt_disk = 25
+ flavor_alt_ram = 1024
+ flavor_alt_vcpus = 1
+ flavor_alt_disk = 3
quota_security_group = 20
quota_security_group_rule = 100
quota_port = 50
+ cop_yaml = ("https://github.com/cloudify-cosmo/cloudify-openstack-plugin/"
+ "releases/download/2.14.7/plugin.yaml")
+ cop_wgn = ("https://github.com/cloudify-cosmo/cloudify-openstack-plugin/"
+ "releases/download/2.14.7/cloudify_openstack_plugin-2.14.7-py27"
+ "-none-linux_x86_64-centos-Core.wgn")
+
def __init__(self, **kwargs):
"""Initialize CloudifyIms testcase object."""
if "case_name" not in kwargs:
kwargs["case_name"] = "cloudify_ims"
- super(CloudifyIms, self).__init__(**kwargs)
+ super().__init__(**kwargs)
# Retrieve the configuration
try:
self.config = getattr(
- config.CONF, 'vnf_{}_config'.format(self.case_name))
- except Exception:
- raise Exception("VNF config file not found")
+ config.CONF, f'vnf_{self.case_name}_config')
+ except Exception as exc:
+ raise Exception("VNF config file not found") from exc
self.case_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/vnf/ims')
config_file = os.path.join(self.case_dir, self.config)
self.details['orchestrator'] = dict(
- name=get_config("orchestrator.name", config_file),
- version=get_config("orchestrator.version", config_file),
+ name=functest_utils.get_parameter_from_yaml(
+ "orchestrator.name", config_file),
+ version=functest_utils.get_parameter_from_yaml(
+ "orchestrator.version", config_file),
status='ERROR',
result=''
)
self.vnf = dict(
- descriptor=get_config("vnf.descriptor", config_file),
- inputs=get_config("vnf.inputs", config_file)
+ descriptor=functest_utils.get_parameter_from_yaml(
+ "vnf.descriptor", config_file),
+ inputs=functest_utils.get_parameter_from_yaml(
+ "vnf.inputs", config_file)
)
self.details['vnf'] = dict(
descriptor_version=self.vnf['descriptor']['version'],
- name=get_config("vnf.name", config_file),
- version=get_config("vnf.version", config_file),
+ name=functest_utils.get_parameter_from_yaml(
+ "vnf.name", config_file),
+ version=functest_utils.get_parameter_from_yaml(
+ "vnf.version", config_file),
)
self.__logger.debug("VNF configuration: %s", self.vnf)
self.details['test_vnf'] = dict(
- name=get_config("vnf_test_suite.name", config_file),
- version=get_config("vnf_test_suite.version", config_file)
+ name=functest_utils.get_parameter_from_yaml(
+ "vnf_test_suite.name", config_file),
+ version=functest_utils.get_parameter_from_yaml(
+ "vnf_test_suite.version", config_file)
)
self.image_alt = None
@@ -91,9 +103,9 @@ class CloudifyIms(cloudify.Cloudify):
def check_requirements(self):
if env.get('NEW_USER_ROLE').lower() == "admin":
- self.__logger.warn(
+ self.__logger.warning(
"Defining NEW_USER_ROLE=admin will easily break the testcase "
- "because Cloudify doesn't manage tenancy (e.g. subnet "
+ "because Cloudify doesn't manage tenancy (e.g. subnet "
"overlapping)")
def execute(self):
@@ -102,7 +114,7 @@ class CloudifyIms(cloudify.Cloudify):
network, security group, fip, VM creation
"""
- assert super(CloudifyIms, self).execute() == 0
+ assert super().execute() == 0
start_time = time.time()
self.orig_cloud.set_network_quotas(
self.project.project.name,
@@ -141,16 +153,8 @@ class CloudifyIms(cloudify.Cloudify):
duration = time.time() - start_time
- self.__logger.info("Put private keypair in manager")
- scpc = scp.SCPClient(self.ssh.get_transport())
- scpc.put(self.key_filename, remote_path='~/cloudify_ims.pem')
- (_, stdout, stderr) = self.ssh.exec_command(
- "sudo cp ~/cloudify_ims.pem /etc/cloudify/ && "
- "sudo chmod 444 /etc/cloudify/cloudify_ims.pem && "
- "sudo yum install -y gcc python-devel python-cmd2 && "
- "cfy status")
- self.__logger.info("output:\n%s", stdout.read())
- self.__logger.info("error:\n%s", stderr.read())
+ self.put_private_key()
+ self.upload_cfy_plugins(self.cop_yaml, self.cop_wgn)
self.details['orchestrator'].update(status='PASS', duration=duration)
@@ -159,7 +163,7 @@ class CloudifyIms(cloudify.Cloudify):
network_name=self.network.name,
key_pair_name=self.keypair.name
))
- if (self.deploy_vnf() and self.test_vnf()):
+ if self.deploy_vnf() and self.test_vnf():
self.result = 100
return 0
self.result = 1/3 * 100
@@ -200,16 +204,16 @@ class CloudifyIms(cloudify.Cloudify):
descriptor.get('name'), descriptor.get('name'),
self.vnf.get('inputs'))
- wait_for_execution(
+ cloudify.wait_for_execution(
self.cfy_client,
- get_execution_id(self.cfy_client, descriptor.get('name')),
+ cloudify.get_execution_id(self.cfy_client, descriptor.get('name')),
self.__logger, timeout=300)
self.__logger.info("Start the VNF Instance deployment")
execution = self.cfy_client.executions.start(
descriptor.get('name'), 'install')
# Show execution log
- execution = wait_for_execution(
+ execution = cloudify.wait_for_execution(
self.cfy_client, execution, self.__logger, timeout=3600)
self.__logger.info(execution)
@@ -220,9 +224,11 @@ class CloudifyIms(cloudify.Cloudify):
ellis_ip = self.cfy_client.deployments.outputs.get(
self.vnf['descriptor'].get('name'))['outputs']['ellis_ip']
- self.clearwater = clearwater.ClearwaterTesting(self.case_name,
- ellis_ip)
- self.clearwater.availability_check_by_creating_numbers()
+ bono_ip = self.cfy_client.deployments.outputs.get(
+ self.vnf['descriptor'].get('name'))['outputs']['bono_ip']
+ self.clearwater = clearwater.ClearwaterTesting(
+ self.case_name, bono_ip, ellis_ip)
+ self.clearwater.availability_check()
self.details['vnf'].update(status='PASS',
duration=time.time() - start_time)
@@ -232,154 +238,25 @@ class CloudifyIms(cloudify.Cloudify):
def test_vnf(self):
"""Run test on clearwater ims instance."""
start_time = time.time()
-
dns_ip = self.cfy_client.deployments.outputs.get(
self.vnf['descriptor'].get('name'))['outputs']['dns_ip']
-
if not dns_ip:
return False
-
- short_result = self.clearwater.run_clearwater_live_test(
- dns_ip=dns_ip,
+ short_result, vnf_test_rate = self.clearwater.run_clearwater_live_test(
public_domain=self.vnf['inputs']["public_domain"])
duration = time.time() - start_time
self.__logger.info(short_result)
- self.details['test_vnf'].update(result=short_result,
- duration=duration)
- try:
- vnf_test_rate = short_result['passed'] / (
- short_result['total'] - short_result['skipped'])
- # orchestrator + vnf + test_vnf
- self.result += vnf_test_rate / 3 * 100
- except ZeroDivisionError:
- self.__logger.error("No test has been executed")
- self.details['test_vnf'].update(status='FAIL')
- return False
- except Exception: # pylint: disable=broad-except
- self.__logger.exception("Cannot calculate results")
+ self.details['test_vnf'].update(result=short_result, duration=duration)
+ self.result += vnf_test_rate / 3 * 100
+ if vnf_test_rate == 0:
self.details['test_vnf'].update(status='FAIL')
- return False
- return True if vnf_test_rate > 0 else False
+ return bool(vnf_test_rate > 0)
def clean(self):
"""Clean created objects/functions."""
- try:
- dep_name = self.vnf['descriptor'].get('name')
- # kill existing execution
- self.__logger.info('Deleting the current deployment')
- exec_list = self.cfy_client.executions.list()
- for execution in exec_list:
- if execution['status'] == "started":
- try:
- self.cfy_client.executions.cancel(
- execution['id'], force=True)
- except Exception: # pylint: disable=broad-except
- self.__logger.warn("Can't cancel the current exec")
-
- execution = self.cfy_client.executions.start(
- dep_name,
- 'uninstall',
- parameters=dict(ignore_failure=True),
- force=True)
-
- wait_for_execution(self.cfy_client, execution, self.__logger)
- self.cfy_client.deployments.delete(
- self.vnf['descriptor'].get('name'))
- self.cfy_client.blueprints.delete(
- self.vnf['descriptor'].get('name'))
- except Exception: # pylint: disable=broad-except
- self.__logger.exception("Some issue during the undeployment ..")
+ self.kill_existing_execution(self.vnf['descriptor'].get('name'))
if self.image_alt:
self.cloud.delete_image(self.image_alt)
if self.flavor_alt:
self.orig_cloud.delete_flavor(self.flavor_alt.id)
- super(CloudifyIms, self).clean()
-
-
-# ----------------------------------------------------------
-#
-# YAML UTILS
-#
-# -----------------------------------------------------------
-def get_config(parameter, file_path):
- """
- Get config parameter.
-
- Returns the value of a given parameter in file.yaml
- parameter must be given in string format with dots
- Example: general.openstack.image_name
- """
- with open(file_path) as config_file:
- file_yaml = yaml.safe_load(config_file)
- config_file.close()
- value = file_yaml
- for element in parameter.split("."):
- value = value.get(element)
- if value is None:
- raise ValueError("The parameter %s is not defined in"
- " reporting.yaml" % parameter)
- return value
-
-
-def wait_for_execution(client, execution, logger, timeout=3600, ):
- """Wait for a workflow execution on Cloudify Manager."""
- # if execution already ended - return without waiting
- if execution.status in Execution.END_STATES:
- return execution
-
- if timeout is not None:
- deadline = time.time() + timeout
-
- # Poll for execution status and execution logs, until execution ends
- # and we receive an event of type in WORKFLOW_END_TYPES
- offset = 0
- batch_size = 50
- event_list = []
- execution_ended = False
- while True:
- event_list = client.events.list(
- execution_id=execution.id,
- _offset=offset,
- _size=batch_size,
- include_logs=True,
- sort='@timestamp').items
-
- offset = offset + len(event_list)
- for event in event_list:
- logger.debug(event.get('message'))
-
- if timeout is not None:
- if time.time() > deadline:
- raise RuntimeError(
- 'execution of operation {0} for deployment {1} '
- 'timed out'.format(execution.workflow_id,
- execution.deployment_id))
- else:
- # update the remaining timeout
- timeout = deadline - time.time()
-
- if not execution_ended:
- execution = client.executions.get(execution.id)
- execution_ended = execution.status in Execution.END_STATES
-
- if execution_ended:
- break
-
- time.sleep(5)
-
- return execution
-
-
-def get_execution_id(client, deployment_id):
- """
- Get the execution id of a env preparation.
-
- network, security group, fip, VM creation
- """
- executions = client.executions.list(deployment_id=deployment_id)
- for execution in executions:
- if execution.workflow_id == 'create_deployment_environment':
- return execution
- raise RuntimeError('Failed to get create_deployment_environment '
- 'workflow execution.'
- 'Available executions: {0}'.format(executions))
+ super().clean()
diff --git a/functest/opnfv_tests/vnf/ims/heat_ims.py b/functest/opnfv_tests/vnf/ims/heat_ims.py
index 3d32b889d..0d4e345a0 100644
--- a/functest/opnfv_tests/vnf/ims/heat_ims.py
+++ b/functest/opnfv_tests/vnf/ims/heat_ims.py
@@ -15,8 +15,9 @@ import logging
import os
import re
import time
-import yaml
+import tempfile
+import paramiko
import pkg_resources
from xtesting.core import testcase
@@ -24,6 +25,7 @@ from functest.core import singlevm
from functest.opnfv_tests.vnf.ims import clearwater
from functest.utils import config
from functest.utils import env
+from functest.utils import functest_utils
__author__ = "Valentin Boucher <valentin.boucher@kontron.com>"
@@ -37,45 +39,59 @@ class HeatIms(singlevm.VmReady2):
filename = ('/home/opnfv/functest/images/'
'ubuntu-14.04-server-cloudimg-amd64-disk1.img')
- flavor_ram = 2048
- flavor_vcpus = 2
- flavor_disk = 25
+ flavor_ram = 1024
+ flavor_vcpus = 1
+ flavor_disk = 3
quota_security_group = 20
quota_security_group_rule = 100
quota_port = 50
+ parameters = {
+ 'private_mgmt_net_cidr': '192.168.100.0/24',
+ 'private_mgmt_net_gateway': '192.168.100.254',
+ 'private_mgmt_net_pool_start': '192.168.100.1',
+ 'private_mgmt_net_pool_end': '192.168.100.253'}
+
def __init__(self, **kwargs):
"""Initialize HeatIms testcase object."""
if "case_name" not in kwargs:
kwargs["case_name"] = "heat_ims"
- super(HeatIms, self).__init__(**kwargs)
+ super().__init__(**kwargs)
# Retrieve the configuration
try:
self.config = getattr(
- config.CONF, 'vnf_{}_config'.format(self.case_name))
- except Exception:
- raise Exception("VNF config file not found")
+ config.CONF, f'vnf_{self.case_name}_config')
+ except Exception as exc:
+ raise Exception("VNF config file not found") from exc
self.case_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/vnf/ims')
config_file = os.path.join(self.case_dir, self.config)
self.vnf = dict(
- descriptor=get_config("vnf.descriptor", config_file),
- parameters=get_config("vnf.inputs", config_file)
+ descriptor=functest_utils.get_parameter_from_yaml(
+ "vnf.descriptor", config_file),
+ parameters=functest_utils.get_parameter_from_yaml(
+ "vnf.inputs", config_file)
)
self.details['vnf'] = dict(
descriptor_version=self.vnf['descriptor']['version'],
- name=get_config("vnf.name", config_file),
- version=get_config("vnf.version", config_file),
+ name=functest_utils.get_parameter_from_yaml(
+ "vnf.name", config_file),
+ version=functest_utils.get_parameter_from_yaml(
+ "vnf.version", config_file),
)
self.__logger.debug("VNF configuration: %s", self.vnf)
self.keypair = None
self.stack = None
self.clearwater = None
self.role = None
+ (_, self.key_filename) = tempfile.mkstemp()
+
+ def create_network_resources(self):
+ pass
def execute(self):
# pylint: disable=too-many-locals,too-many-statements
@@ -96,10 +112,13 @@ class HeatIms(singlevm.VmReady2):
project=self.project.project.id,
domain=self.project.domain.id)
self.keypair = self.cloud.create_keypair(
- '{}-kp_{}'.format(self.case_name, self.guid))
- self.__logger.debug("keypair: %s", self.keypair)
+ f'{self.case_name}-kp_{self.guid}')
+ self.__logger.info("keypair:\n%s", self.keypair.private_key)
+ with open(
+ self.key_filename, 'w', encoding='utf-8') as private_key_file:
+ private_key_file.write(self.keypair.private_key)
- if (self.deploy_vnf() and self.test_vnf()):
+ if self.deploy_vnf() and self.test_vnf():
self.result = 100
return 0
self.result = 1/3 * 100
@@ -119,7 +138,7 @@ class HeatIms(singlevm.VmReady2):
status = testcase.TestCase.EX_RUN_ERROR
try:
assert self.cloud
- assert super(HeatIms, self).run(
+ assert super().run(
**kwargs) == testcase.TestCase.EX_OK
self.result = 0
if not self.execute():
@@ -131,6 +150,22 @@ class HeatIms(singlevm.VmReady2):
self.stop_time = time.time()
return status
+ def _monit(self, username="ubuntu", timeout=60):
+ servers = self.cloud.list_servers(detailed=True)
+ self.__logger.debug("servers: %s", servers)
+ for server in servers:
+ if 'ns' in server.name:
+ break
+ self.__logger.info("server:\n%s", server.name)
+ ssh = paramiko.SSHClient()
+ ssh.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
+ ssh.connect(
+ server.public_v4, username=username,
+ key_filename=self.key_filename, timeout=timeout)
+ (_, stdout, _) = ssh.exec_command('sudo monit summary')
+ self.__logger.info("output:\n%s", stdout.read().decode("utf-8"))
+ ssh.close()
+
def deploy_vnf(self):
"""Deploy Clearwater IMS."""
start_time = time.time()
@@ -138,12 +173,11 @@ class HeatIms(singlevm.VmReady2):
parameters = self.vnf['parameters']
parameters['public_mgmt_net_id'] = self.ext_net.id
- parameters['public_sig_net_id'] = self.ext_net.id
parameters['flavor'] = self.flavor.name
parameters['image'] = self.image.name
parameters['key_name'] = self.keypair.name
parameters['external_mgmt_dns_ip'] = env.get('NAMESERVER')
- parameters['external_sig_dns_ip'] = env.get('NAMESERVER')
+ parameters.update(self.parameters)
self.__logger.info("Create Heat Stack")
self.stack = self.cloud.create_stack(
@@ -152,24 +186,30 @@ class HeatIms(singlevm.VmReady2):
wait=True, **parameters)
self.__logger.debug("stack: %s", self.stack)
+ self._monit()
+
servers = self.cloud.list_servers(detailed=True)
self.__logger.debug("servers: %s", servers)
for server in servers:
if not self.check_regex_in_console(
- server.name, regex='Cloud-init .* finished at ', loop=60):
+ server.name, regex='Cloud-init .* finished at ', loop=1):
return False
if 'ellis' in server.name:
- self.__logger.debug("server: %s", server)
+ self.__logger.debug("ellis: %s", server)
ellis_ip = server.public_v4
+ elif 'bono' in server.name:
+ self.__logger.debug("bono: %s", server)
+ bono_ip = server.public_v4
assert ellis_ip
- self.clearwater = clearwater.ClearwaterTesting(self.case_name,
- ellis_ip)
+ assert bono_ip
+ self.clearwater = clearwater.ClearwaterTesting(
+ self.case_name, bono_ip, ellis_ip)
# This call can take time and many retry because Heat is
# an infrastructure orchestrator so when Heat say "stack created"
# it means that all OpenStack ressources are created but not that
# Clearwater are up and ready (Cloud-Init script still running)
- self.clearwater.availability_check_by_creating_numbers()
+ self.clearwater.availability_check()
duration = time.time() - start_time
@@ -181,35 +221,21 @@ class HeatIms(singlevm.VmReady2):
def test_vnf(self):
"""Run test on clearwater ims instance."""
start_time = time.time()
-
outputs = self.cloud.get_stack(self.stack.id).outputs
self.__logger.debug("stack outputs: %s", outputs)
dns_ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', str(outputs))[0]
-
if not dns_ip:
return False
-
- short_result = self.clearwater.run_clearwater_live_test(
- dns_ip=dns_ip,
+ short_result, vnf_test_rate = self.clearwater.run_clearwater_live_test(
public_domain=self.vnf['parameters']["zone"])
duration = time.time() - start_time
self.__logger.info(short_result)
- self.details['test_vnf'] = dict(result=short_result,
- duration=duration)
- try:
- vnf_test_rate = short_result['passed'] / (
- short_result['total'] - short_result['skipped'])
- # orchestrator + vnf + test_vnf
- self.result += vnf_test_rate / 3 * 100
- except ZeroDivisionError:
- self.__logger.error("No test has been executed")
+ self.details['test_vnf'] = dict(result=short_result, duration=duration)
+ self.result += vnf_test_rate / 3 * 100
+ if vnf_test_rate == 0:
self.details['test_vnf'].update(status='FAIL')
- return False
- except Exception: # pylint: disable=broad-except
- self.__logger.exception("Cannot calculate results")
- self.details['test_vnf'].update(status='FAIL')
- return False
- return True if vnf_test_rate > 0 else False
+ self._monit()
+ return bool(vnf_test_rate > 0)
def clean(self):
"""Clean created objects/functions."""
@@ -222,31 +248,6 @@ class HeatIms(singlevm.VmReady2):
pass
except Exception: # pylint: disable=broad-except
self.__logger.exception("Cannot clean stack ressources")
- super(HeatIms, self).clean()
+ super().clean()
if self.role:
self.orig_cloud.delete_role(self.role.id)
-
-
-# ----------------------------------------------------------
-#
-# YAML UTILS
-#
-# -----------------------------------------------------------
-def get_config(parameter, file_path):
- """
- Get config parameter.
-
- Returns the value of a given parameter in file.yaml
- parameter must be given in string format with dots
- Example: general.openstack.image_name
- """
- with open(file_path) as config_file:
- file_yaml = yaml.safe_load(config_file)
- config_file.close()
- value = file_yaml
- for element in parameter.split("."):
- value = value.get(element)
- if value is None:
- raise ValueError("The parameter %s is not defined in"
- " reporting.yaml" % parameter)
- return value
diff --git a/functest/opnfv_tests/vnf/ims/heat_ims.yaml b/functest/opnfv_tests/vnf/ims/heat_ims.yaml
index 883c4dffe..2ccdc0bf7 100644
--- a/functest/opnfv_tests/vnf/ims/heat_ims.yaml
+++ b/functest/opnfv_tests/vnf/ims/heat_ims.yaml
@@ -4,11 +4,11 @@ orchestrator:
version: '4.0'
vnf:
name: clearwater
- version: '129'
+ version: '130'
descriptor:
file_name: /src/heat_vims/clearwater.yaml
name: clearwater-opnfv
- version: '129'
+ version: '130'
inputs:
zone: clearwater.opnfv
dn_range_start: "6505550000"
diff --git a/functest/opnfv_tests/vnf/router/cloudify_vrouter.py b/functest/opnfv_tests/vnf/router/cloudify_vrouter.py
index e8c8632bd..32d675347 100644
--- a/functest/opnfv_tests/vnf/router/cloudify_vrouter.py
+++ b/functest/opnfv_tests/vnf/router/cloudify_vrouter.py
@@ -15,14 +15,13 @@ import logging
import os
import time
-from cloudify_rest_client.executions import Execution
import pkg_resources
-import scp
from functest.core import cloudify
from functest.opnfv_tests.vnf.router import vrouter_base
from functest.opnfv_tests.vnf.router.utilvnf import Utilvnf
from functest.utils import config
+from functest.utils import env
from functest.utils import functest_utils
@@ -35,23 +34,31 @@ class CloudifyVrouter(cloudify.Cloudify):
__logger = logging.getLogger(__name__)
- filename_alt = '/home/opnfv/functest/images/vyos-1.1.7.img'
+ filename_alt = '/home/opnfv/functest/images/vyos-1.1.8-amd64.qcow2'
- flavor_alt_ram = 2048
+ flavor_alt_ram = 1024
flavor_alt_vcpus = 1
- flavor_alt_disk = 50
+ flavor_alt_disk = 3
+
+ check_console_loop = 12
+
+ cop_yaml = ("https://github.com/cloudify-cosmo/cloudify-openstack-plugin/"
+ "releases/download/2.14.7/plugin.yaml")
+ cop_wgn = ("https://github.com/cloudify-cosmo/cloudify-openstack-plugin/"
+ "releases/download/2.14.7/cloudify_openstack_plugin-2.14.7-py27"
+ "-none-linux_x86_64-centos-Core.wgn")
def __init__(self, **kwargs):
if "case_name" not in kwargs:
kwargs["case_name"] = "vyos_vrouter"
- super(CloudifyVrouter, self).__init__(**kwargs)
+ super().__init__(**kwargs)
# Retrieve the configuration
try:
self.config = getattr(
- config.CONF, 'vnf_{}_config'.format(self.case_name))
- except Exception:
- raise Exception("VNF config file not found")
+ config.CONF, f'vnf_{self.case_name}_config')
+ except Exception as exc:
+ raise Exception("VNF config file not found") from exc
self.case_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/vnf/router')
@@ -106,6 +113,13 @@ class CloudifyVrouter(cloudify.Cloudify):
self.image_alt = None
self.flavor_alt = None
+ def check_requirements(self):
+ if env.get('NEW_USER_ROLE').lower() == "admin":
+ self.__logger.warning(
+ "Defining NEW_USER_ROLE=admin will easily break the testcase "
+ "because Cloudify doesn't manage tenancy (e.g. subnet "
+ "overlapping)")
+
def execute(self):
# pylint: disable=too-many-locals,too-many-statements
"""
@@ -113,18 +127,10 @@ class CloudifyVrouter(cloudify.Cloudify):
network, security group, fip, VM creation
"""
# network creation
- super(CloudifyVrouter, self).execute()
+ super().execute()
start_time = time.time()
- self.__logger.info("Put private keypair in manager")
- scpc = scp.SCPClient(self.ssh.get_transport())
- scpc.put(self.key_filename, remote_path='~/cloudify_ims.pem')
- (_, stdout, stderr) = self.ssh.exec_command(
- "sudo cp ~/cloudify_ims.pem /etc/cloudify/ && "
- "sudo chmod 444 /etc/cloudify/cloudify_ims.pem && "
- "sudo yum install -y gcc python-devel python-cmd2 && "
- "cfy status")
- self.__logger.info("output:\n%s", stdout.read())
- self.__logger.info("error:\n%s", stderr.read())
+ self.put_private_key()
+ self.upload_cfy_plugins(self.cop_yaml, self.cop_wgn)
self.image_alt = self.publish_image_alt()
self.flavor_alt = self.create_flavor_alt()
@@ -181,8 +187,8 @@ class CloudifyVrouter(cloudify.Cloudify):
descriptor.get('name'), descriptor.get('name'),
self.vnf.get('inputs'))
- wait_for_execution(
- self.cfy_client, get_execution_id(
+ cloudify.wait_for_execution(
+ self.cfy_client, cloudify.get_execution_id(
self.cfy_client, descriptor.get('name')),
self.__logger, timeout=7200)
@@ -190,7 +196,7 @@ class CloudifyVrouter(cloudify.Cloudify):
execution = self.cfy_client.executions.start(
descriptor.get('name'), 'install')
# Show execution log
- execution = wait_for_execution(
+ execution = cloudify.wait_for_execution(
self.cfy_client, execution, self.__logger)
duration = time.time() - start_time
@@ -206,8 +212,7 @@ class CloudifyVrouter(cloudify.Cloudify):
def test_vnf(self):
start_time = time.time()
- testing = vrouter_base.VrouterOnBoardingBase(
- self.case_name, self.util, self.util_info)
+ testing = vrouter_base.VrouterOnBoardingBase(self.util, self.util_info)
result, test_result_data = testing.test_vnf()
duration = time.time() - start_time
if result:
@@ -221,91 +226,9 @@ class CloudifyVrouter(cloudify.Cloudify):
return True
def clean(self):
- try:
- dep_name = self.vnf['descriptor'].get('name')
- # kill existing execution
- self.__logger.info('Deleting the current deployment')
- exec_list = self.cfy_client.executions.list()
- for execution in exec_list:
- if execution['status'] == "started":
- try:
- self.cfy_client.executions.cancel(
- execution['id'], force=True)
- except Exception: # pylint: disable=broad-except
- self.__logger.warn("Can't cancel the current exec")
-
- execution = self.cfy_client.executions.start(
- dep_name, 'uninstall', parameters=dict(ignore_failure=True))
-
- wait_for_execution(self.cfy_client, execution, self.__logger)
- self.cfy_client.deployments.delete(
- self.vnf['descriptor'].get('name'))
- self.cfy_client.blueprints.delete(
- self.vnf['descriptor'].get('name'))
- except Exception: # pylint: disable=broad-except
- self.__logger.exception("Some issue during the undeployment ..")
+ self.kill_existing_execution(self.vnf['descriptor'].get('name'))
if self.image_alt:
self.cloud.delete_image(self.image_alt)
if self.flavor_alt:
self.orig_cloud.delete_flavor(self.flavor_alt.id)
- super(CloudifyVrouter, self).clean()
-
-
-def wait_for_execution(client, execution, logger, timeout=7200, ):
- """Wait for a workflow execution on Cloudify Manager."""
- # if execution already ended - return without waiting
- if execution.status in Execution.END_STATES:
- return execution
-
- if timeout is not None:
- deadline = time.time() + timeout
-
- # Poll for execution status and execution logs, until execution ends
- # and we receive an event of type in WORKFLOW_END_TYPES
- offset = 0
- batch_size = 50
- event_list = []
- execution_ended = False
- while True:
- event_list = client.events.list(
- execution_id=execution.id, _offset=offset, _size=batch_size,
- include_logs=True, sort='@timestamp').items
-
- offset = offset + len(event_list)
- for event in event_list:
- logger.debug(event.get('message'))
-
- if timeout is not None:
- if time.time() > deadline:
- raise RuntimeError(
- 'execution of operation {0} for deployment {1} '
- 'timed out'.format(execution.workflow_id,
- execution.deployment_id))
- else:
- # update the remaining timeout
- timeout = deadline - time.time()
-
- if not execution_ended:
- execution = client.executions.get(execution.id)
- execution_ended = execution.status in Execution.END_STATES
-
- if execution_ended:
- break
-
- time.sleep(5)
-
- return execution
-
-
-def get_execution_id(client, deployment_id):
- """
- Get the execution id of a env preparation.
- network, security group, fip, VM creation
- """
- executions = client.executions.list(deployment_id=deployment_id)
- for execution in executions:
- if execution.workflow_id == 'create_deployment_environment':
- return execution
- raise RuntimeError('Failed to get create_deployment_environment '
- 'workflow execution.'
- 'Available executions: {0}'.format(executions))
+ super().clean()
diff --git a/functest/opnfv_tests/vnf/router/test_controller/function_test_exec.py b/functest/opnfv_tests/vnf/router/test_controller/function_test_exec.py
index 0b8a69b73..9eb3c5d69 100644
--- a/functest/opnfv_tests/vnf/router/test_controller/function_test_exec.py
+++ b/functest/opnfv_tests/vnf/router/test_controller/function_test_exec.py
@@ -21,7 +21,7 @@ from functest.opnfv_tests.vnf.router.vnf_controller.vnf_controller import (
VnfController)
-class FunctionTestExec(object):
+class FunctionTestExec():
"""vrouter function test execution class"""
logger = logging.getLogger(__name__)
@@ -32,17 +32,16 @@ class FunctionTestExec(object):
credentials = util_info["credentials"]
self.vnf_ctrl = VnfController(util_info)
- test_cmd_map_file = open(
- os.path.join(
- self.util.vnf_data_dir, self.util.command_template_dir,
- self.util.test_cmd_map_yaml_file),
- 'r')
- self.test_cmd_map_yaml = yaml.safe_load(test_cmd_map_file)
- test_cmd_map_file.close()
+ with open(
+ os.path.join(
+ self.util.vnf_data_dir, self.util.command_template_dir,
+ self.util.test_cmd_map_yaml_file),
+ 'r', encoding='utf-8') as test_cmd_map_file:
+ self.test_cmd_map_yaml = yaml.safe_load(test_cmd_map_file)
self.util.set_credentials(credentials["cloud"])
- with open(self.util.test_env_config_yaml) as file_fd:
+ with open(self.util.test_env_config_yaml, encoding='utf-8') as file_fd:
test_env_config_yaml = yaml.safe_load(file_fd)
file_fd.close()
diff --git a/functest/opnfv_tests/vnf/router/utilvnf.py b/functest/opnfv_tests/vnf/router/utilvnf.py
index a54f6cb0b..111f20c1a 100644
--- a/functest/opnfv_tests/vnf/router/utilvnf.py
+++ b/functest/opnfv_tests/vnf/router/utilvnf.py
@@ -43,7 +43,7 @@ NUMBER_OF_DIGITS_FOR_AVG_JITTER = 3
NUMBER_OF_DIGITS_FOR_AVG_PKT_LOSS = 1
-class Utilvnf(object): # pylint: disable=too-many-instance-attributes
+class Utilvnf(): # pylint: disable=too-many-instance-attributes
""" Utility class of vrouter testcase """
logger = logging.getLogger(__name__)
@@ -64,7 +64,7 @@ class Utilvnf(object): # pylint: disable=too-many-instance-attributes
if not os.path.exists(self.vnf_data_dir):
os.makedirs(self.vnf_data_dir)
- with open(self.test_env_config_yaml) as file_fd:
+ with open(self.test_env_config_yaml, encoding='utf-8') as file_fd:
test_env_config_yaml = yaml.safe_load(file_fd)
file_fd.close()
@@ -98,9 +98,7 @@ class Utilvnf(object): # pylint: disable=too-many-instance-attributes
return mac_address
def get_blueprint_outputs(self, cfy_manager_ip, deployment_name):
- url = "http://%s/deployments/%s/outputs" % (
- cfy_manager_ip, deployment_name)
-
+ url = f"http://{cfy_manager_ip}/deployments/{deployment_name}/outputs"
response = requests.get(
url,
auth=requests.auth.HTTPBasicAuth('admin', 'admin'),
@@ -212,24 +210,29 @@ class Utilvnf(object): # pylint: disable=too-many-instance-attributes
def write_result_data(self, result_data):
test_result = []
if not os.path.isfile(self.test_result_json_file):
- file_fd = open(self.test_result_json_file, "w")
- file_fd.close()
+ with open(
+ self.test_result_json_file, "w",
+ encoding="utf-8") as file_fd:
+ pass
else:
- file_fd = open(self.test_result_json_file, "r")
- test_result = json.load(file_fd)
- file_fd.close()
+ with open(
+ self.test_result_json_file, "r",
+ encoding="utf-8") as file_fd:
+ test_result = json.load(file_fd)
test_result.append(result_data)
- file_fd = open(self.test_result_json_file, "w")
- json.dump(test_result, file_fd)
- file_fd.close()
+ with open(
+ self.test_result_json_file, "w",
+ encoding="utf-8") as file_fd:
+ json.dump(test_result, file_fd)
def output_test_result_json(self):
if os.path.isfile(self.test_result_json_file):
- file_fd = open(self.test_result_json_file, "r")
- test_result = json.load(file_fd)
- file_fd.close()
+ with open(
+ self.test_result_json_file, "r",
+ encoding="utf-8") as file_fd:
+ test_result = json.load(file_fd)
output_json_data = json.dumps(test_result,
sort_keys=True,
indent=4)
@@ -239,8 +242,6 @@ class Utilvnf(object): # pylint: disable=too-many-instance-attributes
@staticmethod
def get_test_scenario(file_path):
- test_scenario_file = open(file_path,
- 'r')
- test_scenario_yaml = yaml.safe_load(test_scenario_file)
- test_scenario_file.close()
+ with open(file_path, "r", encoding="utf-8") as test_scenario_file:
+ test_scenario_yaml = yaml.safe_load(test_scenario_file)
return test_scenario_yaml["test_scenario_list"]
diff --git a/functest/opnfv_tests/vnf/router/vnf_controller/checker.py b/functest/opnfv_tests/vnf/router/vnf_controller/checker.py
index a7a70f6d7..d3a216ed0 100644
--- a/functest/opnfv_tests/vnf/router/vnf_controller/checker.py
+++ b/functest/opnfv_tests/vnf/router/vnf_controller/checker.py
@@ -18,7 +18,7 @@ import re
from jinja2 import Environment, FileSystemLoader
-class Checker(object):
+class Checker():
"""vrouter test result check class"""
logger = logging.getLogger(__name__)
diff --git a/functest/opnfv_tests/vnf/router/vnf_controller/command_generator.py b/functest/opnfv_tests/vnf/router/vnf_controller/command_generator.py
index 7d9116bcc..a86a16485 100644
--- a/functest/opnfv_tests/vnf/router/vnf_controller/command_generator.py
+++ b/functest/opnfv_tests/vnf/router/vnf_controller/command_generator.py
@@ -15,7 +15,7 @@ import logging
from jinja2 import Environment, FileSystemLoader
-class CommandGenerator(object):
+class CommandGenerator():
"""command generator class for vrouter testing"""
logger = logging.getLogger(__name__)
diff --git a/functest/opnfv_tests/vnf/router/vnf_controller/ssh_client.py b/functest/opnfv_tests/vnf/router/vnf_controller/ssh_client.py
index c5f554cbd..269f6526b 100644
--- a/functest/opnfv_tests/vnf/router/vnf_controller/ssh_client.py
+++ b/functest/opnfv_tests/vnf/router/vnf_controller/ssh_client.py
@@ -24,7 +24,7 @@ DEFAULT_CONNECT_RETRY_COUNT = 10
DEFAULT_SEND_TIMEOUT = 10
-class SshClient(object): # pylint: disable=too-many-instance-attributes
+class SshClient(): # pylint: disable=too-many-instance-attributes
"""ssh client class for vrouter testing"""
logger = logging.getLogger(__name__)
@@ -43,7 +43,7 @@ class SshClient(object): # pylint: disable=too-many-instance-attributes
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.util = Utilvnf()
- with open(self.util.test_env_config_yaml) as file_fd:
+ with open(self.util.test_env_config_yaml, encoding='utf-8') as file_fd:
test_env_config_yaml = yaml.safe_load(file_fd)
file_fd.close()
@@ -80,7 +80,7 @@ class SshClient(object): # pylint: disable=too-many-instance-attributes
retrycount -= 1
if retrycount == 0:
- self.logger.warn(
+ self.logger.warning(
"Cannot establish connection to IP '%s'", self.ip_address)
self.connected = False
return self.connected
@@ -110,7 +110,7 @@ class SshClient(object): # pylint: disable=too-many-instance-attributes
cmd)
break
- res_buff += res
+ res_buff += res.decode("utf-8")
self.logger.debug("Response : '%s'", res_buff)
return res_buff
diff --git a/functest/opnfv_tests/vnf/router/vnf_controller/vm_controller.py b/functest/opnfv_tests/vnf/router/vnf_controller/vm_controller.py
index a73855421..2210b3909 100644
--- a/functest/opnfv_tests/vnf/router/vnf_controller/vm_controller.py
+++ b/functest/opnfv_tests/vnf/router/vnf_controller/vm_controller.py
@@ -23,7 +23,7 @@ from functest.opnfv_tests.vnf.router.vnf_controller.ssh_client import (
SshClient)
-class VmController(object):
+class VmController():
"""vm controll class"""
logger = logging.getLogger(__name__)
@@ -36,7 +36,7 @@ class VmController(object):
self.util = Utilvnf()
self.util.set_credentials(credentials["cloud"])
- with open(self.util.test_env_config_yaml) as file_fd:
+ with open(self.util.test_env_config_yaml, encoding='utf-8') as file_fd:
test_env_config_yaml = yaml.safe_load(file_fd)
file_fd.close()
@@ -101,10 +101,8 @@ class VmController(object):
def command_create_and_execute(self, ssh, test_cmd_file_path,
cmd_input_param, prompt_file_path):
- prompt_file = open(prompt_file_path,
- 'r')
- prompt = yaml.safe_load(prompt_file)
- prompt_file.close()
+ with open(prompt_file_path, 'r', encoding='utf-8') as prompt_file:
+ prompt = yaml.safe_load(prompt_file)
config_mode_prompt = prompt["config_mode"]
commands = self.command_gen_from_template(test_cmd_file_path,
diff --git a/functest/opnfv_tests/vnf/router/vnf_controller/vnf_controller.py b/functest/opnfv_tests/vnf/router/vnf_controller/vnf_controller.py
index a5b1ad856..46584456f 100644
--- a/functest/opnfv_tests/vnf/router/vnf_controller/vnf_controller.py
+++ b/functest/opnfv_tests/vnf/router/vnf_controller/vnf_controller.py
@@ -26,7 +26,7 @@ from functest.opnfv_tests.vnf.router.vnf_controller.vm_controller import (
VmController)
-class VnfController(object):
+class VnfController():
"""vrouter controll class"""
logger = logging.getLogger(__name__)
@@ -36,7 +36,7 @@ class VnfController(object):
self.util = Utilvnf()
self.vm_controller = VmController(util_info)
- with open(self.util.test_env_config_yaml) as file_fd:
+ with open(self.util.test_env_config_yaml, encoding='utf-8') as file_fd:
test_env_config_yaml = yaml.safe_load(file_fd)
file_fd.close()
@@ -49,10 +49,9 @@ class VnfController(object):
def config_vnf(self, source_vnf, destination_vnf, test_cmd_file_path,
parameter_file_path, prompt_file_path):
# pylint: disable=too-many-arguments
- parameter_file = open(parameter_file_path,
- 'r')
- cmd_input_param = yaml.safe_load(parameter_file)
- parameter_file.close()
+ with open(
+ parameter_file_path, 'r', encoding='utf-8') as parameter_file:
+ cmd_input_param = yaml.safe_load(parameter_file)
cmd_input_param["macaddress"] = source_vnf["data_plane_network_mac"]
cmd_input_param["source_ip"] = source_vnf["data_plane_network_ip"]
@@ -71,19 +70,16 @@ class VnfController(object):
res_dict_data_list = []
- parameter_file = open(parameter_file_path,
- 'r')
- cmd_input_param = yaml.safe_load(parameter_file)
- parameter_file.close()
+ with open(
+ parameter_file_path, 'r', encoding='utf-8') as parameter_file:
+ cmd_input_param = yaml.safe_load(parameter_file)
cmd_input_param["source_ip"] = target_vnf["data_plane_network_ip"]
cmd_input_param["destination_ip"] = reference_vnf[
"data_plane_network_ip"]
- prompt_file = open(prompt_file_path,
- 'r')
- prompt = yaml.safe_load(prompt_file)
- prompt_file.close()
+ with open(prompt_file_path, 'r', encoding='utf-8') as prompt_file:
+ prompt = yaml.safe_load(prompt_file)
terminal_mode_prompt = prompt["terminal_mode"]
ssh = SshClient(target_vnf["floating_ip"],
diff --git a/functest/opnfv_tests/vnf/router/vrouter_base.py b/functest/opnfv_tests/vnf/router/vrouter_base.py
index e8a933ff5..932770b9c 100644
--- a/functest/opnfv_tests/vnf/router/vrouter_base.py
+++ b/functest/opnfv_tests/vnf/router/vrouter_base.py
@@ -19,28 +19,22 @@ import time
import pkg_resources
-from functest.utils import config
from functest.opnfv_tests.vnf.router.test_controller import function_test_exec
__author__ = "Shuya Nakama <shuya.nakama@okinawaopenlabs.org>"
-class VrouterOnBoardingBase(object):
+class VrouterOnBoardingBase():
"""vrouter testing base class"""
- def __init__(self, case_name, util, util_info):
+ def __init__(self, util, util_info):
self.logger = logging.getLogger(__name__)
self.case_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/vnf/router')
- self.result_dir = os.path.join(
- getattr(config.CONF, 'dir_results'), case_name)
self.util = util
self.util_info = util_info
self.vnf_list = []
- if not os.path.exists(self.result_dir):
- os.makedirs(self.result_dir)
-
def test_vnf(self):
"""vrouter test execution"""
result = False
diff --git a/functest/tests/unit/ci/__init__.py b/functest/tests/unit/ci/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/functest/tests/unit/ci/__init__.py
+++ /dev/null
diff --git a/functest/tests/unit/ci/test_check_deployment.py b/functest/tests/unit/ci/test_check_deployment.py
deleted file mode 100644
index aeeca5871..000000000
--- a/functest/tests/unit/ci/test_check_deployment.py
+++ /dev/null
@@ -1,286 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2017 Ericsson and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-
-# pylint: disable=missing-docstring
-
-import socket
-import unittest
-
-import logging
-import mock
-
-from functest.ci import check_deployment
-
-__author__ = "Jose Lausuch <jose.lausuch@ericsson.com>"
-
-
-class CheckDeploymentTesting(unittest.TestCase):
- """The super class which testing classes could inherit."""
- # pylint: disable=missing-docstring,too-many-public-methods
-
- logging.disable(logging.CRITICAL)
-
- def setUp(self):
- self.client_test = mock.Mock()
- self.deployment = check_deployment.CheckDeployment()
- self.service_test = 'compute'
- self.rc_file = self.deployment.rc_file
- self.endpoint_test = 'http://192.168.0.6:5000/v3'
- creds_attr = {'auth_url': self.endpoint_test,
- 'proxy_settings': ''}
- proxy_attr = {'host': '192.168.0.1', 'port': '5000'}
- proxy_settings = mock.Mock()
- proxy_settings.configure_mock(**proxy_attr)
- self.os_creds = mock.Mock()
- self.os_creds.configure_mock(**creds_attr)
- self.os_creds.proxy_settings = proxy_settings
- self.deployment.os_creds = self.os_creds
-
- @mock.patch('socket.socket.connect', side_effect=TypeError)
- def test_verify_connectivity_ko1(self, *args):
- self.assertFalse(check_deployment.verify_connectivity("127.0.0.1"))
- args[0].assert_called_once_with((None, 80))
-
- @mock.patch('socket.socket.connect', side_effect=socket.error)
- def test_verify_connectivity_ko2(self, *args):
- self.assertFalse(
- check_deployment.verify_connectivity("http://127.0.0.1"))
- args[0].assert_called_once_with(("127.0.0.1", 80))
-
- @mock.patch('socket.socket.connect', side_effect=socket.error)
- def test_verify_connectivity_ko3(self, *args):
- self.assertFalse(
- check_deployment.verify_connectivity("https://127.0.0.1"))
- args[0].assert_called_once_with(("127.0.0.1", 443))
-
- @mock.patch('socket.socket.connect')
- def test_verify_connectivity(self, *args):
- self.assertTrue(
- check_deployment.verify_connectivity("https://127.0.0.1"))
- args[0].assert_called_once_with(("127.0.0.1", 443))
-
- @mock.patch('snaps.openstack.utils.keystone_utils.keystone_session',
- return_value=mock.Mock(
- get_token=mock.Mock(side_effect=Exception)))
- def test_get_auth_token_ko(self, *args):
- with self.assertRaises(Exception):
- check_deployment.get_auth_token(self.os_creds)
- args[0].assert_called_once_with(self.os_creds)
-
- @mock.patch('snaps.openstack.utils.keystone_utils.keystone_session',
- return_value=mock.Mock(
- get_token=mock.Mock(return_value="foo")))
- def test_get_auth_token(self, *args):
- self.assertEqual(check_deployment.get_auth_token(self.os_creds), "foo")
- args[0].assert_called_once_with(self.os_creds)
-
- @mock.patch('six.moves.builtins.open',
- mock.mock_open(read_data='OS_AUTH_URL'))
- @mock.patch('functest.ci.check_deployment.os.path.isfile', returns=True)
- def test_check_rc(self, *args):
- self.deployment.check_rc()
- args[0].assert_called_once_with(self.rc_file)
-
- @mock.patch('functest.ci.check_deployment.os.path.isfile',
- return_value=False)
- def test_check_rc_missing_file(self, *args):
- with self.assertRaises(Exception) as context:
- self.deployment.check_rc()
- args[0].assert_called_once_with(self.rc_file)
- msg = 'RC file {} does not exist!'.format(self.rc_file)
- self.assertTrue(msg in str(context.exception))
-
- @mock.patch('six.moves.builtins.open',
- mock.mock_open(read_data='test'))
- @mock.patch('functest.ci.check_deployment.os.path.isfile',
- return_value=True)
- def test_check_rc_missing_os_auth(self, *args):
- with self.assertRaises(Exception) as context:
- self.deployment.check_rc()
- args[0].assert_called_once_with(self.rc_file)
- msg = 'OS_AUTH_URL not defined in {}.'.format(self.rc_file)
- self.assertTrue(msg in str(context.exception))
-
- @mock.patch('functest.ci.check_deployment.get_auth_token',
- return_value='gAAAAABaOhXGS')
- @mock.patch('functest.ci.check_deployment.verify_connectivity',
- return_value=True)
- def test_check_auth_endpoint(self, *args):
- self.deployment.check_auth_endpoint()
- args[0].assert_called_once_with(self.endpoint_test)
- args[1].assert_called_once_with(mock.ANY)
-
- @mock.patch('functest.ci.check_deployment.verify_connectivity',
- return_value=False)
- def test_check_auth_endpoint_ko(self, *args):
- with self.assertRaises(Exception) as context:
- self.deployment.check_auth_endpoint()
- msg = "OS_AUTH_URL {} is not reachable.".format(self.os_creds.auth_url)
- args[0].assert_called_once_with(self.os_creds.auth_url)
- self.assertTrue(msg in str(context.exception))
-
- @mock.patch('functest.ci.check_deployment.verify_connectivity',
- return_value=True)
- @mock.patch('functest.ci.check_deployment.keystone_utils.get_endpoint')
- def test_check_public_endpoint(self, *args):
- args[0].return_value = self.endpoint_test
- self.deployment.check_public_endpoint()
- args[0].assert_called_once_with(
- mock.ANY, 'identity', interface='public')
- args[1].assert_called_once_with(self.endpoint_test)
-
- @mock.patch('functest.ci.check_deployment.verify_connectivity',
- return_value=False)
- @mock.patch('functest.ci.check_deployment.keystone_utils.get_endpoint')
- def test_check_public_endpoint_ko(self, *args):
- args[0].return_value = self.endpoint_test
- with self.assertRaises(Exception) as context:
- self.deployment.check_public_endpoint()
- args[0].assert_called_once_with(
- mock.ANY, 'identity', interface='public')
- args[1].assert_called_once_with(self.endpoint_test)
- msg = "Public endpoint {} is not reachable.".format(self.endpoint_test)
- self.assertTrue(msg in str(context.exception))
-
- @mock.patch('functest.ci.check_deployment.verify_connectivity',
- return_value=True)
- @mock.patch('functest.ci.check_deployment.keystone_utils.get_endpoint')
- def test_check_service_endpoint(self, *args):
- self.deployment.check_service_endpoint(self.service_test)
- args[0].assert_called_once_with(
- mock.ANY, self.service_test, interface='public')
- args[1].assert_called_once_with(args[0].return_value)
-
- @mock.patch('functest.ci.check_deployment.verify_connectivity',
- return_value=False)
- @mock.patch('functest.ci.check_deployment.keystone_utils.get_endpoint')
- def test_check_service_endpoint_ko(self, *args):
- args[0].return_value = self.endpoint_test
- with self.assertRaises(Exception) as context:
- self.deployment.check_service_endpoint(self.service_test)
- msg = "{} endpoint {} is not reachable.".format(
- self.service_test, self.endpoint_test)
- self.assertTrue(msg in str(context.exception))
- args[0].assert_called_once_with(
- mock.ANY, self.service_test, interface='public')
- args[1].assert_called_once_with(args[0].return_value)
-
- @mock.patch('functest.ci.check_deployment.nova_utils.nova_client')
- def test_check_nova(self, mock_method):
- self.deployment.check_nova()
- mock_method.assert_called_once_with(mock.ANY)
-
- @mock.patch('functest.ci.check_deployment.nova_utils.nova_client',
- return_value=mock.Mock(
- servers=mock.Mock(list=mock.Mock(side_effect=Exception))))
- def test_check_nova_fail(self, mock_method):
- with self.assertRaises(Exception):
- self.deployment.check_nova()
- mock_method.assert_called_once_with(mock.ANY)
-
- @mock.patch('functest.ci.check_deployment.neutron_utils.neutron_client')
- def test_check_neutron(self, mock_method):
- self.deployment.check_neutron()
- mock_method.assert_called_once_with(mock.ANY)
-
- @mock.patch('functest.ci.check_deployment.neutron_utils.neutron_client',
- return_value=mock.Mock(
- list_networks=mock.Mock(side_effect=Exception)))
- def test_check_neutron_fail(self, mock_method):
- with self.assertRaises(Exception):
- self.deployment.check_neutron()
- mock_method.assert_called_once_with(mock.ANY)
-
- @mock.patch('functest.ci.check_deployment.glance_utils.glance_client')
- def test_check_glance(self, mock_method):
- self.deployment.check_glance()
- mock_method.assert_called_once_with(mock.ANY)
-
- @mock.patch('functest.ci.check_deployment.glance_utils.glance_client',
- return_value=mock.Mock(
- images=mock.Mock(list=mock.Mock(side_effect=Exception))))
- def test_check_glance_fail(self, mock_method):
- with self.assertRaises(Exception):
- self.deployment.check_glance()
- mock_method.assert_called_once_with(mock.ANY)
-
- @mock.patch('functest.ci.check_deployment.LOGGER.info')
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
- 'get_ext_net_name', return_value='ext-net')
- def test_check_extnet(self, *args):
- self.deployment.check_ext_net()
- args[0].assert_called_once_with(mock.ANY)
- args[1].assert_called_once_with(
- "External network found: %s", "ext-net")
-
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
- 'get_ext_net_name', return_value='')
- def test_check_extnet_none(self, mock_getext):
- with self.assertRaises(Exception) as context:
- self.deployment.check_ext_net()
- self.assertTrue(mock_getext.called)
- msg = 'ERROR: No external networks in the deployment.'
- self.assertTrue(msg in str(context.exception))
-
- @mock.patch('functest.ci.check_deployment.CheckDeployment.check_rc',
- side_effect=Exception)
- def test_check_all_exc1(self, *args):
- with self.assertRaises(Exception):
- self.deployment.check_all()
- args[0].assert_called_once_with()
-
- @mock.patch('snaps.openstack.tests.openstack_tests.get_credentials',
- side_effect=Exception)
- @mock.patch('functest.ci.check_deployment.CheckDeployment.check_rc')
- def test_check_all_exc2(self, *args):
- with self.assertRaises(Exception):
- self.deployment.check_all()
- args[0].assert_called_once_with()
- args[1].assert_called_once_with(
- os_env_file=self.rc_file, proxy_settings_str=None,
- ssh_proxy_cmd=None)
-
- @mock.patch('snaps.openstack.tests.openstack_tests.get_credentials',
- return_value=None)
- @mock.patch('functest.ci.check_deployment.CheckDeployment.check_rc')
- def test_check_all_exc3(self, *args):
- with self.assertRaises(Exception):
- self.deployment.check_all()
- args[0].assert_called_once_with()
- args[1].assert_called_once_with(
- os_env_file=self.rc_file, proxy_settings_str=None,
- ssh_proxy_cmd=None)
-
- @mock.patch('functest.ci.check_deployment.CheckDeployment.check_ext_net')
- @mock.patch('functest.ci.check_deployment.CheckDeployment.check_glance')
- @mock.patch('functest.ci.check_deployment.CheckDeployment.check_neutron')
- @mock.patch('functest.ci.check_deployment.CheckDeployment.check_nova')
- @mock.patch(
- 'functest.ci.check_deployment.CheckDeployment.check_service_endpoint')
- @mock.patch(
- 'functest.ci.check_deployment.CheckDeployment.check_public_endpoint')
- @mock.patch(
- 'functest.ci.check_deployment.CheckDeployment.check_auth_endpoint')
- @mock.patch('snaps.openstack.tests.openstack_tests.get_credentials')
- @mock.patch('functest.ci.check_deployment.CheckDeployment.check_rc')
- def test_check_all(self, *args):
- self.assertEqual(self.deployment.check_all(), 0)
- for i in [0, 2, 3, 5, 6, 7, 8]:
- args[i].assert_called_once_with()
- args[1].assert_called_once_with(
- os_env_file=self.rc_file, proxy_settings_str=None,
- ssh_proxy_cmd=None)
- calls = [mock.call('compute'), mock.call('network'),
- mock.call('image')]
- args[4].assert_has_calls(calls)
-
-
-if __name__ == "__main__":
- logging.disable(logging.CRITICAL)
- unittest.main(verbosity=2)
diff --git a/functest/tests/unit/odl/test_odl.py b/functest/tests/unit/odl/test_odl.py
index 1b2e10b07..c675c2988 100644
--- a/functest/tests/unit/odl/test_odl.py
+++ b/functest/tests/unit/odl/test_odl.py
@@ -33,10 +33,10 @@ class ODLTesting(unittest.TestCase):
logging.disable(logging.CRITICAL)
_keystone_ip = "127.0.0.1"
- _neutron_url = u"https://127.0.0.1:9696"
- _neutron_id = u"dummy"
+ _neutron_url = "https://127.0.0.1:9696"
+ _neutron_id = "dummy"
_sdn_controller_ip = "127.0.0.3"
- _os_auth_url = "http://{}:5000/v3".format(_keystone_ip)
+ _os_auth_url = f"http://{_keystone_ip}:5000/v3"
_os_projectname = "admin"
_os_username = "admin"
_os_password = "admin"
@@ -63,8 +63,7 @@ class ODLTesting(unittest.TestCase):
self.test = odl.ODLTests(case_name='odl', project_name='functest')
self.defaultargs = {'odlusername': self._odl_username,
'odlpassword': self._odl_password,
- 'neutronurl': "http://{}:9696".format(
- self._keystone_ip),
+ 'neutronurl': f"http://{self._keystone_ip}:9696",
'osauthurl': self._os_auth_url,
'osusername': self._os_username,
'osuserdomainname': self._os_userdomainname,
@@ -105,7 +104,7 @@ class ODLRobotTesting(ODLTesting):
mock_method.assert_called_once_with(
os.path.join(odl.ODLTests.odl_test_repo,
'csit/variables/Variables.robot'), inplace=True)
- self.assertEqual(args[0].getvalue(), "{}\n".format(msg2))
+ self.assertEqual(args[0].getvalue(), f"{msg2}\n")
def test_set_vars_auth_default(self):
self._test_set_vars(
@@ -160,19 +159,19 @@ class ODLMainTesting(ODLTesting):
args[0].assert_called_once_with(self.test.odl_variables_file)
if len(args) > 1:
variable = [
- 'KEYSTONEURL:{}://{}'.format(
- urllib.parse.urlparse(self._os_auth_url).scheme,
- urllib.parse.urlparse(self._os_auth_url).netloc),
- 'NEUTRONURL:{}'.format(self._neutron_url),
- 'OS_AUTH_URL:"{}"'.format(self._os_auth_url),
- 'OSUSERNAME:"{}"'.format(self._os_username),
- 'OSUSERDOMAINNAME:"{}"'.format(self._os_userdomainname),
- 'OSTENANTNAME:"{}"'.format(self._os_projectname),
- 'OSPROJECTDOMAINNAME:"{}"'.format(self._os_projectdomainname),
- 'OSPASSWORD:"{}"'.format(self._os_password),
- 'ODL_SYSTEM_IP:{}'.format(self._sdn_controller_ip),
- 'PORT:{}'.format(self._odl_webport),
- 'RESTCONFPORT:{}'.format(self._odl_restconfport)]
+ ('KEYSTONEURL:'
+ f'{urllib.parse.urlparse(self._os_auth_url).scheme}://'
+ f'{urllib.parse.urlparse(self._os_auth_url).netloc}'),
+ f'NEUTRONURL:{self._neutron_url}',
+ f'OS_AUTH_URL:"{self._os_auth_url}"',
+ f'OSUSERNAME:"{self._os_username}"',
+ f'OSUSERDOMAINNAME:"{self._os_userdomainname}"',
+ f'OSTENANTNAME:"{self._os_projectname}"',
+ f'OSPROJECTDOMAINNAME:"{self._os_projectdomainname}"',
+ f'OSPASSWORD:"{self._os_password}"',
+ f'ODL_SYSTEM_IP:{self._sdn_controller_ip}',
+ f'PORT:{self._odl_webport}',
+ f'RESTCONFPORT:{self._odl_restconfport}']
args[1].assert_called_once_with(
odl.ODLTests.basic_suite_dir, odl.ODLTests.neutron_suite_dir,
include=[],
@@ -541,7 +540,7 @@ class ODLArgParserTesting(ODLTesting):
def setUp(self):
self.parser = odl.ODLParser()
- super(ODLArgParserTesting, self).setUp()
+ super().setUp()
def test_default(self):
self.assertEqual(self.parser.parse_args(), self.defaultargs)
@@ -551,8 +550,8 @@ class ODLArgParserTesting(ODLTesting):
self.defaultargs['odlip'] = self._sdn_controller_ip
self.assertEqual(
self.parser.parse_args(
- ["--neutronurl={}".format(self._neutron_url),
- "--odlip={}".format(self._sdn_controller_ip)]),
+ [f"--neutronurl={self._neutron_url}",
+ f"--odlip={self._sdn_controller_ip}"]),
self.defaultargs)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@@ -565,7 +564,7 @@ class ODLArgParserTesting(ODLTesting):
def _test_arg(self, arg, value):
self.defaultargs[arg] = value
self.assertEqual(
- self.parser.parse_args(["--{}={}".format(arg, value)]),
+ self.parser.parse_args([f"--{arg}={value}"]),
self.defaultargs)
def test_odlusername(self):
@@ -606,7 +605,7 @@ class ODLArgParserTesting(ODLTesting):
def test_pushtodb(self):
self.defaultargs['pushtodb'] = True
- self.assertEqual(self.parser.parse_args(["--{}".format('pushtodb')]),
+ self.assertEqual(self.parser.parse_args(["--pushtodb"]),
self.defaultargs)
def test_multiple_args(self):
@@ -614,8 +613,8 @@ class ODLArgParserTesting(ODLTesting):
self.defaultargs['odlip'] = self._sdn_controller_ip
self.assertEqual(
self.parser.parse_args(
- ["--neutronurl={}".format(self._neutron_url),
- "--odlip={}".format(self._sdn_controller_ip)]),
+ [f"--neutronurl={self._neutron_url}",
+ f"--odlip={self._sdn_controller_ip}"]),
self.defaultargs)
diff --git a/functest/tests/unit/openstack/cinder/test_cinder.py b/functest/tests/unit/openstack/cinder/test_cinder.py
index 4052408d9..d3c9cabb6 100644
--- a/functest/tests/unit/openstack/cinder/test_cinder.py
+++ b/functest/tests/unit/openstack/cinder/test_cinder.py
@@ -59,7 +59,7 @@ class CinderTesting(unittest.TestCase):
self.cinder.prepare()
args[0].assert_called_with()
args[1].assert_called_once_with(
- '{}-vm2_{}'.format(self.cinder.case_name, self.cinder.guid),
+ f'{self.cinder.case_name}-vm2_{self.cinder.guid}',
security_groups=[self.cinder.sec.id],
key_name=self.cinder.keypair.id)
self.cinder.cloud.create_volume.assert_not_called()
@@ -81,13 +81,12 @@ class CinderTesting(unittest.TestCase):
self.cinder.prepare()
args[0].assert_called_once_with()
args[1].assert_called_once_with(
- '{}-vm2_{}'.format(self.cinder.case_name, self.cinder.guid),
+ f'{self.cinder.case_name}-vm2_{self.cinder.guid}',
security_groups=[self.cinder.sec.id],
key_name=self.cinder.keypair.id)
self.cinder.connect.assert_called_once_with(args[1].return_value)
self.cinder.cloud.create_volume.assert_called_once_with(
- name='{}-volume_{}'.format(
- self.cinder.case_name, self.cinder.guid),
+ name=f'{self.cinder.case_name}-volume_{self.cinder.guid}',
size='2', timeout=self.cinder.volume_timeout, wait=True)
@mock.patch('scp.SCPClient.put')
@@ -101,7 +100,7 @@ class CinderTesting(unittest.TestCase):
self.cinder.ssh.exec_command.return_value = (None, stdout, mock.Mock())
self.assertEqual(self.cinder._write_data(), 0)
self.cinder.ssh.exec_command.assert_called_once_with(
- "sh ~/write_data.sh {}".format(env.get('VOLUME_DEVICE_NAME')))
+ f"sh ~/write_data.sh {env.get('VOLUME_DEVICE_NAME')}")
self.cinder.cloud.attach_volume.assert_called_once_with(
self.cinder.sshvm, self.cinder.volume,
timeout=self.cinder.volume_timeout)
@@ -138,7 +137,7 @@ class CinderTesting(unittest.TestCase):
stdout.channel.recv_exit_status.return_value = 0
self.assertEqual(self.cinder._read_data(), 0)
self.cinder.ssh2.exec_command.assert_called_once_with(
- "sh ~/read_data.sh {}".format(env.get('VOLUME_DEVICE_NAME')))
+ f"sh ~/read_data.sh {env.get('VOLUME_DEVICE_NAME')}")
self.cinder.cloud.attach_volume.assert_called_once_with(
self.cinder.vm2, self.cinder.volume,
timeout=self.cinder.volume_timeout)
diff --git a/functest/tests/unit/openstack/rally/test_rally.py b/functest/tests/unit/openstack/rally/test_rally.py
index 149925730..f3c2e7cf6 100644
--- a/functest/tests/unit/openstack/rally/test_rally.py
+++ b/functest/tests/unit/openstack/rally/test_rally.py
@@ -10,6 +10,7 @@
import json
import logging
import os
+import subprocess
import unittest
import mock
@@ -17,6 +18,7 @@ import munch
from xtesting.core import testcase
from functest.opnfv_tests.openstack.rally import rally
+from functest.utils import config
class OSRallyTesting(unittest.TestCase):
@@ -30,7 +32,6 @@ class OSRallyTesting(unittest.TestCase):
self.rally_base.image = munch.Munch(name='foo')
self.rally_base.flavor = munch.Munch(name='foo')
self.rally_base.flavor_alt = munch.Munch(name='bar')
- self.rally_base.test_name = 'all'
self.assertTrue(mock_get_config.called)
self.assertTrue(mock_shade.called)
self.assertTrue(mock_new_project.called)
@@ -38,18 +39,18 @@ class OSRallyTesting(unittest.TestCase):
def test_build_task_args_missing_floating_network(self):
os.environ['OS_AUTH_URL'] = ''
self.rally_base.ext_net = None
- task_args = self.rally_base._build_task_args('test_file_name')
+ task_args = self.rally_base.build_task_args('test_name')
self.assertEqual(task_args['floating_network'], '')
def test_build_task_args_missing_net_id(self):
os.environ['OS_AUTH_URL'] = ''
self.rally_base.network = None
- task_args = self.rally_base._build_task_args('test_file_name')
+ task_args = self.rally_base.build_task_args('test_name')
self.assertEqual(task_args['netid'], '')
@staticmethod
def check_scenario_file(value):
- yaml_file = 'opnfv-{}.yaml'.format('test_file_name')
+ yaml_file = 'opnfv-test_file_name.yaml'
if yaml_file in value:
return False
return True
@@ -63,11 +64,29 @@ class OSRallyTesting(unittest.TestCase):
@staticmethod
def check_temp_dir(value):
- yaml_file = 'opnfv-{}.yaml'.format('test_file_name')
+ yaml_file = 'opnfv-test_file_name.yaml'
if yaml_file in value:
return True
return False
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.'
+ 'RallyBase.get_verifier_deployment_id', return_value='foo')
+ @mock.patch('subprocess.check_output')
+ def test_create_rally_deployment(self, mock_exec, mock_get_id):
+ # pylint: disable=unused-argument
+ self.assertEqual(rally.RallyBase.create_rally_deployment(), 'foo')
+ calls = [
+ mock.call(['rally', 'deployment', 'destroy', '--deployment',
+ str(getattr(config.CONF, 'rally_deployment_name'))]),
+ mock.call().decode("utf-8"),
+ mock.call(['rally', 'deployment', 'create', '--fromenv', '--name',
+ str(getattr(config.CONF, 'rally_deployment_name'))],
+ env=None),
+ mock.call().decode("utf-8"),
+ mock.call(['rally', 'deployment', 'check']),
+ mock.call().decode("utf-8")]
+ mock_exec.assert_has_calls(calls)
+
@mock.patch('functest.opnfv_tests.openstack.rally.rally.os.path.exists')
@mock.patch('functest.opnfv_tests.openstack.rally.rally.os.makedirs')
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
@@ -76,23 +95,27 @@ class OSRallyTesting(unittest.TestCase):
self, mock_method, mock_os_makedirs, mock_path_exists):
mock_path_exists.side_effect = self.check_temp_dir
- yaml_file = 'opnfv-{}.yaml'.format('test_file_name')
- ret_val = os.path.join(self.rally_base.TEMP_DIR, yaml_file)
+ yaml_file = 'opnfv-test_file_name.yaml'
+ ret_val = os.path.join(self.rally_base.temp_dir, yaml_file)
self.assertEqual(self.rally_base._prepare_test_list('test_file_name'),
ret_val)
mock_path_exists.assert_called()
mock_method.assert_called()
mock_os_makedirs.assert_called()
- def test_get_task_id_default(self):
- cmd_raw = 'Task 1: started'
- self.assertEqual(self.rally_base.get_task_id(cmd_raw),
- '1')
+ @mock.patch('subprocess.check_output', return_value=b'1\n')
+ def test_get_task_id_default(self, *args):
+ tag = 'nova'
+ self.assertEqual(self.rally_base.get_task_id(tag), '1')
+ args[0].assert_called_with(
+ ['rally', 'task', 'list', '--tag', tag, '--uuids-only'])
- def test_get_task_id_missing_id(self):
- cmd_raw = ''
- self.assertEqual(self.rally_base.get_task_id(cmd_raw),
- None)
+ @mock.patch('subprocess.check_output', return_value=b'\n')
+ def test_get_task_id_missing_id(self, *args):
+ tag = 'nova'
+ self.assertEqual(self.rally_base.get_task_id(tag), '')
+ args[0].assert_called_with(
+ ['rally', 'task', 'list', '--tag', tag, '--uuids-only'])
def test_task_succeed_fail(self):
json_raw = json.dumps({})
@@ -206,7 +229,7 @@ class OSRallyTesting(unittest.TestCase):
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'file_is_empty', return_value=False)
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
- '_build_task_args', return_value={})
+ 'build_task_args', return_value={})
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'get_task_id', return_value=None)
@mock.patch('functest.opnfv_tests.openstack.rally.rally.os.path.exists',
@@ -226,7 +249,7 @@ class OSRallyTesting(unittest.TestCase):
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'file_is_empty', return_value=False)
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
- '_build_task_args', return_value={})
+ 'build_task_args', return_value={})
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'get_task_id', return_value='1')
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
@@ -261,10 +284,9 @@ class OSRallyTesting(unittest.TestCase):
mock_summary.assert_called()
def test_prepare_run_testname_invalid(self):
- self.rally_base.TESTS = ['test1', 'test2']
- self.rally_base.test_name = 'test'
+ self.rally_base.stests = ['test1', 'test2']
with self.assertRaises(Exception):
- self.rally_base.prepare_run()
+ self.rally_base.prepare_run(tests=['test'])
@mock.patch('functest.opnfv_tests.openstack.rally.rally.os.path.exists')
@mock.patch('functest.opnfv_tests.openstack.rally.rally.shutil.copyfile')
@@ -272,15 +294,14 @@ class OSRallyTesting(unittest.TestCase):
@mock.patch('functest.opnfv_tests.openstack.rally.rally.shutil.rmtree')
def test_prepare_run_flavor_alt_creation_failed(self, *args):
# pylint: disable=unused-argument
- self.rally_base.TESTS = ['test1', 'test2']
- self.rally_base.test_name = 'test1'
- with mock.patch.object(self.rally_base.cloud,
- 'list_hypervisors') as mock_list_hyperv, \
+ self.rally_base.stests = ['test1', 'test2']
+ with mock.patch.object(self.rally_base, 'count_hypervisors') \
+ as mock_list_hyperv, \
mock.patch.object(self.rally_base, 'create_flavor_alt',
side_effect=Exception) \
as mock_create_flavor:
with self.assertRaises(Exception):
- self.rally_base.prepare_run()
+ self.rally_base.prepare_run(tests=['test1'])
mock_list_hyperv.assert_called_once()
mock_create_flavor.assert_called_once()
@@ -290,7 +311,6 @@ class OSRallyTesting(unittest.TestCase):
'run_task')
def test_run_tests_all(self, mock_run_task, mock_prepare_task):
self.rally_base.tests = ['test1', 'test2']
- self.rally_base.test_name = 'all'
self.rally_base.run_tests()
mock_prepare_task.assert_any_call('test1')
mock_prepare_task.assert_any_call('test2')
@@ -309,14 +329,19 @@ class OSRallyTesting(unittest.TestCase):
mock_run_task.assert_any_call('test1')
mock_run_task.assert_any_call('test2')
- def test_clean_up_default(self):
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
+ 'clean_rally_logs')
+ def test_clean_up_default(self, *args):
with mock.patch.object(self.rally_base.orig_cloud,
'delete_flavor') as mock_delete_flavor:
self.rally_base.flavor_alt = mock.Mock()
self.rally_base.clean()
self.assertEqual(mock_delete_flavor.call_count, 1)
+ args[0].assert_called_once_with()
- @mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
+ 'update_rally_logs')
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'create_rally_deployment')
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'prepare_run')
@@ -324,18 +349,25 @@ class OSRallyTesting(unittest.TestCase):
'run_tests')
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'_generate_report')
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
+ 'export_task')
def test_run_default(self, *args):
self.assertEqual(self.rally_base.run(), testcase.TestCase.EX_OK)
for func in args:
func.assert_called()
- @mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
+ 'update_rally_logs')
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'create_rally_deployment', side_effect=Exception)
- def test_run_exception_create_rally_dep(self, mock_create_rally_dep):
+ def test_run_exception_create_rally_dep(self, *args):
self.assertEqual(self.rally_base.run(), testcase.TestCase.EX_RUN_ERROR)
- mock_create_rally_dep.assert_called()
+ args[0].assert_called()
+ args[1].assert_called_once_with(self.rally_base.res_dir)
- @mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
+ 'update_rally_logs')
+ @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'create_rally_deployment', return_value=mock.Mock())
@mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
'prepare_run', side_effect=Exception)
@@ -343,16 +375,34 @@ class OSRallyTesting(unittest.TestCase):
# pylint: disable=unused-argument
self.assertEqual(self.rally_base.run(), testcase.TestCase.EX_RUN_ERROR)
mock_prep_env.assert_called()
+ args[1].assert_called_once_with(self.rally_base.res_dir)
def test_append_summary(self):
- text = '{"tasks": [{"subtasks": [{"workloads": [{"full_duration": ' \
- '1.23,"data": [{"error": []}]}]},{"workloads": ' \
- '[{"full_duration": 2.78, "data": [{"error": ["err"]}]}]}]}]}'
- self.rally_base._append_summary(text, "foo_test")
+ json_dict = {
+ 'tasks': [{
+ 'subtasks': [{
+ 'title': 'sub_task',
+ 'workloads': [{
+ 'full_duration': 1.23,
+ 'data': [{
+ 'error': []
+ }]
+ }, {
+ 'full_duration': 2.78,
+ 'data': [{
+ 'error': ['err']
+ }]
+ }]
+ }]
+ }]
+ }
+ self.rally_base._append_summary(json.dumps(json_dict), "foo_test")
self.assertEqual(self.rally_base.summary[0]['test_name'], "foo_test")
self.assertEqual(self.rally_base.summary[0]['overall_duration'], 4.01)
self.assertEqual(self.rally_base.summary[0]['nb_tests'], 2)
self.assertEqual(self.rally_base.summary[0]['nb_success'], 1)
+ self.assertEqual(self.rally_base.summary[0]['success'], [])
+ self.assertEqual(self.rally_base.summary[0]['failures'], ['sub_task'])
def test_is_successful_false(self):
with mock.patch('six.moves.builtins.super') as mock_super:
@@ -370,6 +420,48 @@ class OSRallyTesting(unittest.TestCase):
self.assertEqual(self.rally_base.is_successful(), 424)
mock_super(rally.RallyBase, self).is_successful.assert_called()
+ @mock.patch('subprocess.check_output',
+ side_effect=subprocess.CalledProcessError('', ''))
+ def test_export_task_ko(self, *args):
+ file_name = (f"{self.rally_base.results_dir}/"
+ f"{self.rally_base.case_name}.html")
+ with self.assertRaises(subprocess.CalledProcessError):
+ self.rally_base.export_task(file_name)
+ cmd = ["rally", "task", "export", "--type", "html", "--deployment",
+ str(getattr(config.CONF, 'rally_deployment_name')),
+ "--to", file_name]
+ args[0].assert_called_with(cmd, stderr=subprocess.STDOUT)
+
+ @mock.patch('subprocess.check_output', return_value=b'')
+ def test_export_task(self, *args):
+ file_name = (f"{self.rally_base.results_dir}/"
+ f"{self.rally_base.case_name}.html")
+ self.assertEqual(self.rally_base.export_task(file_name), None)
+ cmd = ["rally", "task", "export", "--type", "html", "--deployment",
+ str(getattr(config.CONF, 'rally_deployment_name')),
+ "--to", file_name]
+ args[0].assert_called_with(cmd, stderr=subprocess.STDOUT)
+
+ @mock.patch('subprocess.check_output',
+ side_effect=subprocess.CalledProcessError('', ''))
+ def test_verify_report_ko(self, *args):
+ file_name = (f"{self.rally_base.results_dir}/"
+ f"{self.rally_base.case_name}.html")
+ with self.assertRaises(subprocess.CalledProcessError):
+ self.rally_base.verify_report(file_name, "1")
+ cmd = ["rally", "verify", "report", "--type", "html", "--uuid", "1",
+ "--to", file_name]
+ args[0].assert_called_with(cmd, stderr=subprocess.STDOUT)
+
+ @mock.patch('subprocess.check_output', return_value=b'')
+ def test_verify_report(self, *args):
+ file_name = (f"{self.rally_base.results_dir}/"
+ f"{self.rally_base.case_name}.html")
+ self.assertEqual(self.rally_base.verify_report(file_name, "1"), None)
+ cmd = ["rally", "verify", "report", "--type", "html", "--uuid", "1",
+ "--to", file_name]
+ args[0].assert_called_with(cmd, stderr=subprocess.STDOUT)
+
if __name__ == "__main__":
logging.disable(logging.CRITICAL)
diff --git a/functest/tests/unit/openstack/snaps/__init__.py b/functest/tests/unit/openstack/snaps/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/functest/tests/unit/openstack/snaps/__init__.py
+++ /dev/null
diff --git a/functest/tests/unit/openstack/snaps/test_snaps.py b/functest/tests/unit/openstack/snaps/test_snaps.py
deleted file mode 100644
index 14bc38596..000000000
--- a/functest/tests/unit/openstack/snaps/test_snaps.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# Copyright (c) 2017 Cable Television Laboratories, Inc. and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-
-# pylint: disable=missing-docstring
-
-import logging
-import unittest
-
-import mock
-from snaps.openstack.os_credentials import OSCreds
-from xtesting.core import testcase
-
-from functest.opnfv_tests.openstack.snaps import api_check
-from functest.opnfv_tests.openstack.snaps import health_check
-from functest.opnfv_tests.openstack.snaps import smoke
-
-
-class APICheckTesting(unittest.TestCase):
- """
- Ensures the ApiCheck class can run in Functest. This test does not
- actually connect with an OpenStack pod.
- """
-
- def setUp(self):
- self.os_creds = OSCreds(
- username='user', password='pass',
- auth_url='http://foo.com:5000/v3', project_name='bar')
- with mock.patch('os_client_config.get_config') as mock_get_config, \
- mock.patch('shade.OpenStackCloud') as mock_shade, \
- mock.patch('functest.core.tenantnetwork.NewProject') \
- as mock_new_project:
- self.api_check = api_check.ApiCheck(
- os_creds=self.os_creds, ext_net_name='foo')
- mock_get_config.assert_called()
- mock_shade.assert_called()
- mock_new_project.assert_called()
-
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_suite_builder.'
- 'add_openstack_client_tests')
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_suite_builder.'
- 'add_openstack_api_tests')
- @mock.patch('unittest.TextTestRunner.run',
- return_value=mock.MagicMock(name='unittest.TextTestResult'))
- def test_run_success(self, *args):
- args[0].return_value.testsRun = 100
- args[0].return_value.failures = []
- args[0].return_value.errors = []
- self.assertEquals(testcase.TestCase.EX_OK, self.api_check.run())
- self.assertEquals(
- testcase.TestCase.EX_OK, self.api_check.is_successful())
- args[0].assert_called_with(mock.ANY)
- args[1].assert_called_with(
- ext_net_name='foo', image_metadata=mock.ANY,
- os_creds=self.os_creds, suite=mock.ANY, use_keystone=True)
-
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_suite_builder.'
- 'add_openstack_client_tests')
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_suite_builder.'
- 'add_openstack_api_tests')
- @mock.patch('unittest.TextTestRunner.run',
- return_value=mock.MagicMock(name='unittest.TextTestResult'))
- def test_run_1_of_100_ko(self, *args):
- args[0].return_value.testsRun = 100
- args[0].return_value.failures = ['foo']
- args[0].return_value.errors = []
- self.assertEquals(testcase.TestCase.EX_OK, self.api_check.run())
- self.assertEquals(
- testcase.TestCase.EX_TESTCASE_FAILED,
- self.api_check.is_successful())
- args[0].assert_called_with(mock.ANY)
- args[1].assert_called_with(
- ext_net_name='foo', image_metadata=mock.ANY,
- os_creds=self.os_creds, suite=mock.ANY, use_keystone=True)
-
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_suite_builder.'
- 'add_openstack_client_tests')
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_suite_builder.'
- 'add_openstack_api_tests')
- @mock.patch('unittest.TextTestRunner.run',
- return_value=mock.MagicMock(name='unittest.TextTestResult'))
- def test_run_1_of_100_ko_criteria(self, *args):
- self.api_check.criteria = 90
- args[0].return_value.testsRun = 100
- args[0].return_value.failures = ['foo']
- args[0].return_value.errors = []
- self.assertEquals(testcase.TestCase.EX_OK, self.api_check.run())
- self.assertEquals(
- testcase.TestCase.EX_OK, self.api_check.is_successful())
- args[0].assert_called_with(mock.ANY)
- args[1].assert_called_with(
- ext_net_name='foo', image_metadata=mock.ANY,
- os_creds=self.os_creds, suite=mock.ANY, use_keystone=True)
-
-
-class HealthCheckTesting(unittest.TestCase):
- """
- Ensures the HealthCheck class can run in Functest. This test does not
- actually connect with an OpenStack pod.
- """
-
- def setUp(self):
- self.os_creds = OSCreds(
- username='user', password='pass',
- auth_url='http://foo.com:5000/v3', project_name='bar')
- with mock.patch('os_client_config.get_config') as mock_get_config, \
- mock.patch('shade.OpenStackCloud') as mock_shade, \
- mock.patch('functest.core.tenantnetwork.NewProject') \
- as mock_new_project:
- self.health_check = health_check.HealthCheck(
- os_creds=self.os_creds, ext_net_name='foo')
- mock_get_config.assert_called()
- mock_shade.assert_called()
- mock_new_project.assert_called()
-
- @mock.patch('snaps.openstack.tests.os_source_file_test.'
- 'OSIntegrationTestCase.parameterize')
- @mock.patch('unittest.TextTestRunner.run',
- return_value=mock.MagicMock(name='unittest.TextTestResult'))
- def test_run_success(self, *args):
- args[0].return_value.testsRun = 100
- args[0].return_value.failures = []
- args[0].return_value.errors = []
- self.assertEquals(testcase.TestCase.EX_OK, self.health_check.run())
- self.assertEquals(
- testcase.TestCase.EX_OK, self.health_check.is_successful())
- args[0].assert_called_with(mock.ANY)
- args[1].assert_called_with(
- mock.ANY, ext_net_name='foo', flavor_metadata=mock.ANY,
- image_metadata=mock.ANY, netconf_override=None,
- os_creds=self.os_creds, use_keystone=True)
-
- @mock.patch('snaps.openstack.tests.os_source_file_test.'
- 'OSIntegrationTestCase.parameterize')
- @mock.patch('unittest.TextTestRunner.run',
- return_value=mock.MagicMock(name='unittest.TextTestResult'))
- def test_run_1_of_100_ko(self, *args):
- args[0].return_value.testsRun = 100
- args[0].return_value.failures = ['foo']
- args[0].return_value.errors = []
- self.assertEquals(testcase.TestCase.EX_OK, self.health_check.run())
- self.assertEquals(
- testcase.TestCase.EX_TESTCASE_FAILED,
- self.health_check.is_successful())
- args[0].assert_called_with(mock.ANY)
- args[1].assert_called_with(
- mock.ANY, ext_net_name='foo', flavor_metadata=mock.ANY,
- image_metadata=mock.ANY, netconf_override=None,
- os_creds=self.os_creds, use_keystone=True)
-
- @mock.patch('snaps.openstack.tests.os_source_file_test.'
- 'OSIntegrationTestCase.parameterize')
- @mock.patch('unittest.TextTestRunner.run',
- return_value=mock.MagicMock(name='unittest.TextTestResult'))
- def test_run_1_of_100_ko_criteria(self, *args):
- self.health_check.criteria = 90
- args[0].return_value.testsRun = 100
- args[0].return_value.failures = ['foo']
- args[0].return_value.errors = []
- self.assertEquals(testcase.TestCase.EX_OK, self.health_check.run())
- self.assertEquals(
- testcase.TestCase.EX_OK, self.health_check.is_successful())
- args[0].assert_called_with(mock.ANY)
- args[1].assert_called_with(
- mock.ANY, ext_net_name='foo', flavor_metadata=mock.ANY,
- image_metadata=mock.ANY, netconf_override=None,
- os_creds=self.os_creds, use_keystone=True)
-
-
-class SmokeTesting(unittest.TestCase):
- """
- Ensures the SnapsSmoke class can run in Functest. This test does not
- actually connect with an OpenStack pod.
- """
-
- def setUp(self):
- self.os_creds = OSCreds(
- username='user', password='pass',
- auth_url='http://foo.com:5000/v3', project_name='bar')
- with mock.patch('os_client_config.get_config') as mock_get_config, \
- mock.patch('shade.OpenStackCloud') as mock_shade, \
- mock.patch('functest.core.tenantnetwork.NewProject') \
- as mock_new_project:
- self.smoke = smoke.SnapsSmoke(
- os_creds=self.os_creds, ext_net_name='foo')
- mock_get_config.assert_called()
- mock_shade.assert_called()
- mock_new_project.assert_called()
-
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_suite_builder.'
- 'add_openstack_integration_tests')
- @mock.patch('unittest.TextTestRunner.run',
- return_value=mock.MagicMock(name='unittest.TextTestResult'))
- def test_run_success(self, *args):
- args[0].return_value.testsRun = 100
- args[0].return_value.failures = []
- args[0].return_value.errors = []
- self.assertEquals(testcase.TestCase.EX_OK, self.smoke.run())
- self.assertEquals(testcase.TestCase.EX_OK, self.smoke.is_successful())
- args[0].assert_called_with(mock.ANY)
- args[1].assert_called_with(
- ext_net_name='foo', flavor_metadata=mock.ANY,
- image_metadata=mock.ANY, netconf_override=None,
- os_creds=self.os_creds, suite=mock.ANY, use_floating_ips=True,
- use_keystone=True)
-
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_suite_builder.'
- 'add_openstack_integration_tests')
- @mock.patch('unittest.TextTestRunner.run',
- return_value=mock.MagicMock(name='unittest.TextTestResult'))
- def test_run_1_of_100_ko(self, *args):
- args[0].return_value.testsRun = 100
- args[0].return_value.failures = ['foo']
- args[0].return_value.errors = []
- self.assertEquals(testcase.TestCase.EX_OK, self.smoke.run())
- self.assertEquals(
- testcase.TestCase.EX_TESTCASE_FAILED, self.smoke.is_successful())
- args[0].assert_called_with(mock.ANY)
- args[1].assert_called_with(
- ext_net_name='foo', flavor_metadata=mock.ANY,
- image_metadata=mock.ANY, netconf_override=mock.ANY,
- os_creds=self.os_creds, suite=mock.ANY, use_floating_ips=True,
- use_keystone=True)
-
- @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_suite_builder.'
- 'add_openstack_integration_tests')
- @mock.patch('unittest.TextTestRunner.run',
- return_value=mock.MagicMock(name='unittest.TextTestResult'))
- def test_run_1_of_100_ko_criteria(self, *args):
- self.smoke.criteria = 90
- args[0].return_value.testsRun = 100
- args[0].return_value.failures = ['foo']
- args[0].return_value.errors = []
- self.assertEquals(testcase.TestCase.EX_OK, self.smoke.run())
- self.assertEquals(
- testcase.TestCase.EX_OK, self.smoke.is_successful())
- args[0].assert_called_with(mock.ANY)
- args[1].assert_called_with(
- ext_net_name='foo', flavor_metadata=mock.ANY,
- image_metadata=mock.ANY, netconf_override=None,
- os_creds=self.os_creds, suite=mock.ANY, use_floating_ips=True,
- use_keystone=True)
-
-
-if __name__ == "__main__":
- logging.disable(logging.CRITICAL)
- unittest.main(verbosity=2)
diff --git a/functest/tests/unit/openstack/tempest/test_conf_utils.py b/functest/tests/unit/openstack/tempest/test_conf_utils.py
deleted file mode 100644
index 19b07ba3e..000000000
--- a/functest/tests/unit/openstack/tempest/test_conf_utils.py
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env python
-
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-
-# pylint: disable=missing-docstring
-
-import logging
-import os
-import unittest
-
-import mock
-
-from functest.opnfv_tests.openstack.tempest import conf_utils
-from functest.utils import config
-
-
-class OSTempestConfUtilsTesting(unittest.TestCase):
- # pylint: disable=too-many-public-methods
-
- @mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils'
- '.get_verifier_deployment_id', return_value='foo')
- @mock.patch('subprocess.check_output')
- def test_create_rally_deployment(self, mock_exec, mock_get_id):
- # pylint: disable=unused-argument
- self.assertEqual(conf_utils.create_rally_deployment(), 'foo')
- calls = [
- mock.call(['rally', 'deployment', 'destroy', '--deployment',
- str(getattr(config.CONF, 'rally_deployment_name'))]),
- mock.call(['rally', 'deployment', 'create', '--fromenv', '--name',
- str(getattr(config.CONF, 'rally_deployment_name'))],
- env=None),
- mock.call(['rally', 'deployment', 'check'])]
- mock_exec.assert_has_calls(calls)
-
- @mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils'
- '.LOGGER.debug')
- def test_create_verifier(self, mock_logger_debug):
- mock_popen = mock.Mock()
- attrs = {'poll.return_value': None,
- 'stdout.readline.return_value': '0'}
- mock_popen.configure_mock(**attrs)
-
- setattr(config.CONF, 'tempest_verifier_name', 'test_verifier_name')
- with mock.patch('subprocess.Popen', side_effect=Exception), \
- self.assertRaises(Exception):
- conf_utils.create_verifier()
- mock_logger_debug.assert_any_call("Tempest test_verifier_name"
- " does not exist")
-
- @mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
- 'create_verifier', return_value=mock.Mock())
- @mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
- 'create_rally_deployment', return_value=mock.Mock())
- def test_get_verifier_id_default(self, mock_rally, mock_tempest):
- # pylint: disable=unused-argument
- setattr(config.CONF, 'tempest_verifier_name', 'test_verifier_name')
- with mock.patch('functest.opnfv_tests.openstack.tempest.'
- 'conf_utils.subprocess.Popen') as mock_popen:
- mock_stdout = mock.Mock()
- attrs = {'stdout.readline.return_value': 'test_deploy_id'}
- mock_stdout.configure_mock(**attrs)
- mock_popen.return_value = mock_stdout
-
- self.assertEqual(conf_utils.get_verifier_id(),
- 'test_deploy_id')
-
- def test_get_depl_id_default(self):
- setattr(config.CONF, 'tempest_verifier_name', 'test_deploy_name')
- with mock.patch('functest.opnfv_tests.openstack.tempest.'
- 'conf_utils.subprocess.Popen') as mock_popen:
- mock_stdout = mock.Mock()
- attrs = {'stdout.readline.return_value': 'test_deploy_id'}
- mock_stdout.configure_mock(**attrs)
- mock_popen.return_value = mock_stdout
-
- self.assertEqual(conf_utils.get_verifier_deployment_id(),
- 'test_deploy_id')
-
- def test_get_verif_repo_dir_default(self):
- with mock.patch('functest.opnfv_tests.openstack.tempest.'
- 'conf_utils.os.path.join',
- return_value='test_verifier_repo_dir'):
- self.assertEqual(conf_utils.get_verifier_repo_dir(''),
- 'test_verifier_repo_dir')
-
- def test_get_depl_dir_default(self):
- with mock.patch('functest.opnfv_tests.openstack.tempest.'
- 'conf_utils.os.path.join',
- return_value='test_verifier_repo_dir'):
- self.assertEqual(conf_utils.get_verifier_deployment_dir('', ''),
- 'test_verifier_repo_dir')
-
- def _test_missing_param(self, params, image_id, flavor_id, alt=False):
- with mock.patch('six.moves.configparser.RawConfigParser.'
- 'set') as mset, \
- mock.patch('six.moves.configparser.RawConfigParser.'
- 'read') as mread, \
- mock.patch('six.moves.configparser.RawConfigParser.'
- 'write') as mwrite, \
- mock.patch('six.moves.builtins.open', mock.mock_open()), \
- mock.patch('functest.utils.functest_utils.yaml.safe_load',
- return_value={'validation': {'ssh_timeout': 300}}):
- os.environ['OS_INTERFACE'] = ''
- if not alt:
- conf_utils.configure_tempest_update_params(
- 'test_conf_file', image_id=image_id,
- flavor_id=flavor_id)
- mset.assert_any_call(params[0], params[1], params[2])
- else:
- conf_utils.configure_tempest_update_params(
- 'test_conf_file', image_alt_id=image_id,
- flavor_alt_id=flavor_id)
- mset.assert_any_call(params[0], params[1], params[2])
- self.assertTrue(mread.called)
- self.assertTrue(mwrite.called)
-
- def test_upd_missing_image_id(self):
- self._test_missing_param(('compute', 'image_ref', 'test_image_id'),
- 'test_image_id', None)
-
- def test_upd_missing_image_id_alt(self):
- self._test_missing_param(
- ('compute', 'image_ref_alt', 'test_image_id_alt'),
- 'test_image_id_alt', None, alt=True)
-
- def test_upd_missing_flavor_id(self):
- self._test_missing_param(('compute', 'flavor_ref', 'test_flavor_id'),
- None, 'test_flavor_id')
-
- def test_upd_missing_flavor_id_alt(self):
- self._test_missing_param(
- ('compute', 'flavor_ref_alt', 'test_flavor_id_alt'),
- None, 'test_flavor_id_alt', alt=True)
-
- def test_verif_missing_conf_file(self):
- with mock.patch('functest.opnfv_tests.openstack.tempest.'
- 'conf_utils.os.path.isfile',
- return_value=False), \
- mock.patch('subprocess.check_output') as mexe, \
- self.assertRaises(Exception) as context:
- conf_utils.configure_verifier('test_dep_dir')
- mexe.assert_called_once_with("rally verify configure-verifier")
- msg = ("Tempest configuration file 'test_dep_dir/tempest.conf'"
- " NOT found.")
- self.assertTrue(msg in context.exception)
-
- def test_configure_verifier_default(self):
- with mock.patch('functest.opnfv_tests.openstack.tempest.'
- 'conf_utils.os.path.isfile',
- return_value=True), \
- mock.patch('subprocess.check_output') as mexe:
- self.assertEqual(conf_utils.configure_verifier('test_dep_dir'),
- 'test_dep_dir/tempest.conf')
- mexe.assert_called_once_with(
- ['rally', 'verify', 'configure-verifier', '--reconfigure',
- '--id', str(getattr(config.CONF, 'tempest_verifier_name'))])
-
-
-if __name__ == "__main__":
- logging.disable(logging.CRITICAL)
- unittest.main(verbosity=2)
diff --git a/functest/tests/unit/openstack/tempest/test_tempest.py b/functest/tests/unit/openstack/tempest/test_tempest.py
index c87c0b085..efc4393c8 100644
--- a/functest/tests/unit/openstack/tempest/test_tempest.py
+++ b/functest/tests/unit/openstack/tempest/test_tempest.py
@@ -14,8 +14,8 @@ import unittest
import mock
from xtesting.core import testcase
+from functest.opnfv_tests.openstack.rally import rally
from functest.opnfv_tests.openstack.tempest import tempest
-from functest.opnfv_tests.openstack.tempest import conf_utils
from functest.utils import config
@@ -26,21 +26,21 @@ class OSTempestTesting(unittest.TestCase):
with mock.patch('os_client_config.get_config'), \
mock.patch('shade.OpenStackCloud'), \
mock.patch('functest.core.tenantnetwork.NewProject'), \
+ mock.patch('functest.opnfv_tests.openstack.rally.rally.'
+ 'RallyBase.create_rally_deployment'), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'conf_utils.create_rally_deployment'), \
+ 'TempestCommon.create_verifier'), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'conf_utils.create_verifier'), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'conf_utils.get_verifier_id',
+ 'TempestCommon.get_verifier_id',
return_value='test_deploy_id'), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'conf_utils.get_verifier_deployment_id',
+ mock.patch('functest.opnfv_tests.openstack.rally.rally.'
+ 'RallyBase.get_verifier_deployment_id',
return_value='test_deploy_id'), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'conf_utils.get_verifier_repo_dir',
+ 'TempestCommon.get_verifier_repo_dir',
return_value='test_verifier_repo_dir'), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'conf_utils.get_verifier_deployment_dir',
+ 'TempestCommon.get_verifier_deployment_dir',
return_value='test_verifier_deploy_dir'), \
mock.patch('os_client_config.make_shade'):
self.tempestcommon = tempest.TempestCommon()
@@ -57,7 +57,7 @@ class OSTempestTesting(unittest.TestCase):
msg = "Tempest test list file %s NOT found."
self.tempestcommon.generate_test_list()
self.assertTrue(
- (msg % conf_utils.TEMPEST_CUSTOM) in context.exception)
+ (msg % self.tempestcommon.tempest_custom) in context.exception)
@mock.patch('subprocess.check_output')
@mock.patch('os.remove')
@@ -82,8 +82,9 @@ class OSTempestTesting(unittest.TestCase):
else:
testr_mode = self.tempestcommon.mode
verifier_repo_dir = 'test_verifier_repo_dir'
- cmd = "(cd {0}; stestr list '{1}' >{2} 2>/dev/null)".format(
- verifier_repo_dir, testr_mode, self.tempestcommon.list)
+ self.tempestcommon.verifier_repo_dir = verifier_repo_dir
+ cmd = (f"(cd {verifier_repo_dir}; stestr list '{testr_mode}' > "
+ f"{self.tempestcommon.list} 2>/dev/null)")
self.tempestcommon.generate_test_list(mode=testr_mode)
args[0].assert_called_once_with(cmd, shell=True)
args[2].assert_called_once_with('/etc/tempest.conf')
@@ -122,9 +123,10 @@ class OSTempestTesting(unittest.TestCase):
mock.mock_open()) as mock_open, \
mock.patch.object(self.tempestcommon, 'read_file',
return_value=['test1', 'test2']):
- conf_utils.TEMPEST_BLACKLIST = Exception
+ self.tempestcommon.tempest_blacklist = Exception
os.environ['DEPLOY_SCENARIO'] = 'deploy_scenario'
- self.tempestcommon.apply_tempest_blacklist()
+ self.tempestcommon.apply_tempest_blacklist(
+ self.tempestcommon.tempest_blacklist)
obj = mock_open()
obj.write.assert_any_call('test1\n')
obj.write.assert_any_call('test2\n')
@@ -146,7 +148,8 @@ class OSTempestTesting(unittest.TestCase):
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'yaml.safe_load', return_value=item_dict):
os.environ['DEPLOY_SCENARIO'] = 'deploy_scenario'
- self.tempestcommon.apply_tempest_blacklist()
+ self.tempestcommon.apply_tempest_blacklist(
+ self.tempestcommon.tempest_blacklist)
obj = mock_open()
obj.write.assert_any_call('test1\n')
self.assertFalse(obj.write.assert_any_call('test2\n'))
@@ -155,35 +158,17 @@ class OSTempestTesting(unittest.TestCase):
args[2].assert_called_once_with(
self.tempestcommon.list, self.tempestcommon.raw_list)
- @mock.patch('functest.opnfv_tests.openstack.tempest.tempest.LOGGER.info')
- def test_run_verifier_tests_default(self, mock_logger_info):
- with mock.patch('six.moves.builtins.open', mock.mock_open()), \
- mock.patch('six.moves.builtins.iter',
- return_value=[r'\} tempest\.']), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'subprocess.Popen'):
- conf_utils.TEMPEST_LIST = 'test_tempest_list'
- cmd = ["rally", "verify", "start", "--load-list",
- conf_utils.TEMPEST_LIST]
- with self.assertRaises(Exception):
- self.tempestcommon.run_verifier_tests()
- mock_logger_info. \
- assert_any_call("Starting Tempest test suite: '%s'.", cmd)
-
@mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'subprocess.Popen')
- def test_generate_report(self, mock_popen):
- self.tempestcommon.verification_id = "1234"
- html_file = os.path.join(
- os.path.join(
- getattr(config.CONF, 'dir_results'),
- self.tempestcommon.case_name),
- "tempest-report.html")
- cmd = ["rally", "verify", "report", "--type", "html", "--uuid",
- "1234", "--to", html_file]
- self.tempestcommon.generate_report()
- mock_popen.assert_called_once_with(cmd, stdout=mock.ANY,
- stderr=mock.ANY)
+ @mock.patch('six.moves.builtins.open', mock.mock_open())
+ @mock.patch('functest.opnfv_tests.openstack.tempest.tempest.LOGGER.info')
+ def test_run_verifier_tests_default(self, *args):
+ self.tempestcommon.tempest_list = 'test_tempest_list'
+ cmd = ["rally", "verify", "start", "--load-list",
+ self.tempestcommon.tempest_list]
+ with self.assertRaises(Exception):
+ self.tempestcommon.run_verifier_tests()
+ args[0].assert_any_call("Starting Tempest test suite: '%s'.", cmd)
@mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'os.path.exists', return_value=False)
@@ -228,9 +213,9 @@ class OSTempestTesting(unittest.TestCase):
def test_run_apply_blacklist_ko(self):
with mock.patch.object(self.tempestcommon, 'generate_test_list'), \
- mock.patch.object(
- self.tempestcommon, 'apply_tempest_blacklist',
- side_effect=Exception()):
+ mock.patch.object(self.tempestcommon,
+ 'apply_tempest_blacklist',
+ side_effect=Exception()):
self._test_run(testcase.TestCase.EX_RUN_ERROR)
def test_run_verifier_tests_ko(self):
@@ -261,11 +246,147 @@ class OSTempestTesting(unittest.TestCase):
'apply_tempest_blacklist'), \
mock.patch.object(self.tempestcommon, 'run_verifier_tests'), \
mock.patch.object(self.tempestcommon,
- 'parse_verifier_result'), \
- mock.patch.object(self.tempestcommon, 'generate_report'):
+ 'parse_verifier_result'):
self._test_run(testcase.TestCase.EX_OK)
args[0].assert_called_once_with()
+ @mock.patch('functest.opnfv_tests.openstack.tempest.tempest.LOGGER.debug')
+ def test_create_verifier(self, mock_logger_debug):
+ mock_popen = mock.Mock()
+ attrs = {'poll.return_value': None,
+ 'stdout.readline.return_value': '0'}
+ mock_popen.configure_mock(**attrs)
+
+ setattr(config.CONF, 'tempest_verifier_name', 'test_verifier_name')
+ with mock.patch('subprocess.Popen', side_effect=Exception), \
+ self.assertRaises(Exception):
+ self.tempestcommon.create_verifier()
+ mock_logger_debug.assert_any_call("Tempest test_verifier_name"
+ " does not exist")
+
+ def test_get_verifier_id_default(self):
+ setattr(config.CONF, 'tempest_verifier_name', 'test_verifier_name')
+
+ with mock.patch('functest.opnfv_tests.openstack.tempest.'
+ 'tempest.subprocess.Popen') as mock_popen:
+ attrs = {'return_value.__enter__.return_value.'
+ 'stdout.readline.return_value': b'test_deploy_id'}
+ mock_popen.configure_mock(**attrs)
+
+ self.assertEqual(self.tempestcommon.get_verifier_id(),
+ 'test_deploy_id')
+
+ def test_get_depl_id_default(self):
+ setattr(config.CONF, 'tempest_verifier_name', 'test_deploy_name')
+ with mock.patch('functest.opnfv_tests.openstack.tempest.'
+ 'tempest.subprocess.Popen') as mock_popen:
+ attrs = {'return_value.__enter__.return_value.'
+ 'stdout.readline.return_value': b'test_deploy_id'}
+ mock_popen.configure_mock(**attrs)
+
+ self.assertEqual(rally.RallyBase.get_verifier_deployment_id(),
+ 'test_deploy_id')
+
+ def test_get_verif_repo_dir_default(self):
+ with mock.patch('functest.opnfv_tests.openstack.tempest.'
+ 'tempest.os.path.join',
+ return_value='test_verifier_repo_dir'):
+ self.assertEqual(self.tempestcommon.get_verifier_repo_dir(''),
+ 'test_verifier_repo_dir')
+
+ def test_get_depl_dir_default(self):
+ with mock.patch('functest.opnfv_tests.openstack.tempest.'
+ 'tempest.os.path.join',
+ return_value='test_verifier_repo_dir'):
+ self.assertEqual(
+ self.tempestcommon.get_verifier_deployment_dir('', ''),
+ 'test_verifier_repo_dir')
+
+ def _test_missing_param(self, params, image_id, flavor_id, alt=False):
+ with mock.patch('six.moves.configparser.RawConfigParser.'
+ 'set') as mset, \
+ mock.patch('six.moves.configparser.RawConfigParser.'
+ 'read') as mread, \
+ mock.patch('six.moves.configparser.RawConfigParser.'
+ 'write') as mwrite, \
+ mock.patch('six.moves.builtins.open', mock.mock_open()), \
+ mock.patch('functest.utils.functest_utils.yaml.safe_load',
+ return_value={'validation': {'ssh_timeout': 300}}):
+ os.environ['OS_INTERFACE'] = ''
+ if not alt:
+ self.tempestcommon.configure_tempest_update_params(
+ 'test_conf_file', image_id=image_id,
+ flavor_id=flavor_id)
+ mset.assert_any_call(params[0], params[1], params[2])
+ else:
+ self.tempestcommon.configure_tempest_update_params(
+ 'test_conf_file', image_alt_id=image_id,
+ flavor_alt_id=flavor_id)
+ mset.assert_any_call(params[0], params[1], params[2])
+ self.assertTrue(mread.called)
+ self.assertTrue(mwrite.called)
+
+ def test_upd_missing_image_id(self):
+ self._test_missing_param(('compute', 'image_ref', 'test_image_id'),
+ 'test_image_id', None)
+
+ def test_upd_missing_image_id_alt(self):
+ self._test_missing_param(
+ ('compute', 'image_ref_alt', 'test_image_id_alt'),
+ 'test_image_id_alt', None, alt=True)
+
+ def test_upd_missing_flavor_id(self):
+ self._test_missing_param(('compute', 'flavor_ref', 'test_flavor_id'),
+ None, 'test_flavor_id')
+
+ def test_upd_missing_flavor_id_alt(self):
+ self._test_missing_param(
+ ('compute', 'flavor_ref_alt', 'test_flavor_id_alt'),
+ None, 'test_flavor_id_alt', alt=True)
+
+ def test_verif_missing_conf_file(self):
+ with mock.patch('functest.opnfv_tests.openstack.tempest.'
+ 'tempest.os.path.isfile',
+ return_value=False), \
+ mock.patch('subprocess.check_output') as mexe, \
+ self.assertRaises(Exception) as context:
+ self.tempestcommon.configure_verifier('test_dep_dir')
+ mexe.assert_called_once_with("rally verify configure-verifier")
+ msg = ("Tempest configuration file 'test_dep_dir/tempest.conf'"
+ " NOT found.")
+ self.assertTrue(msg in context.exception)
+
+ def test_configure_verifier_default(self):
+ with mock.patch('functest.opnfv_tests.openstack.tempest.'
+ 'tempest.os.path.isfile',
+ return_value=True), \
+ mock.patch('subprocess.check_output') as mexe:
+ self.assertEqual(
+ self.tempestcommon.configure_verifier('test_dep_dir'),
+ 'test_dep_dir/tempest.conf')
+ mexe.assert_called_once_with(
+ ['rally', 'verify', 'configure-verifier', '--reconfigure',
+ '--id', str(getattr(config.CONF, 'tempest_verifier_name'))])
+
+ def test_is_successful_false(self):
+ with mock.patch('six.moves.builtins.super') as mock_super:
+ self.tempestcommon.deny_skipping = True
+ self.tempestcommon.details = {"skipped_number": 2}
+ self.assertEqual(self.tempestcommon.is_successful(),
+ testcase.TestCase.EX_TESTCASE_FAILED)
+ mock_super(tempest.TempestCommon,
+ self).is_successful.assert_not_called()
+
+ def test_is_successful_true(self):
+ with mock.patch('six.moves.builtins.super') as mock_super:
+ self.tempestcommon.deny_skipping = False
+ self.tempestcommon.details = {"skipped_number": 2}
+ mock_super(tempest.TempestCommon,
+ self).is_successful.return_value = 567
+ self.assertEqual(self.tempestcommon.is_successful(), 567)
+ mock_super(tempest.TempestCommon,
+ self).is_successful.assert_called()
+
if __name__ == "__main__":
logging.disable(logging.CRITICAL)
diff --git a/functest/tests/unit/openstack/vmtp/test_vmtp.py b/functest/tests/unit/openstack/vmtp/test_vmtp.py
index fcbb0c46b..850273476 100644
--- a/functest/tests/unit/openstack/vmtp/test_vmtp.py
+++ b/functest/tests/unit/openstack/vmtp/test_vmtp.py
@@ -66,21 +66,22 @@ class VmtpTesting(unittest.TestCase):
def test_generate_keys1(self, *args):
self.testcase.generate_keys()
self.testcase.cloud.create_keypair.assert_called_once_with(
- 'vmtp_{}'.format(self.testcase.guid))
+ f'vmtp_{self.testcase.guid}')
self.testcase.cloud.delete_keypair.assert_called_once_with('id')
- calls = [mock.call(self.testcase.privkey_filename, 'w'),
- mock.call(self.testcase.pubkey_filename, 'w')]
+ calls = [mock.call(
+ self.testcase.privkey_filename, 'w', encoding='utf-8'),
+ mock.call(
+ self.testcase.pubkey_filename, 'w', encoding='utf-8')]
args[0].assert_has_calls(calls, any_order=True)
@mock.patch('six.moves.builtins.open')
def test_generate_keys2(self, *args):
- # pylint: disable=bad-continuation
with mock.patch.object(
self.testcase.cloud, "create_keypair",
side_effect=shade.OpenStackCloudException(None)) as mock_obj, \
self.assertRaises(shade.OpenStackCloudException):
self.testcase.generate_keys()
- mock_obj.assert_called_once_with('vmtp_{}'.format(self.testcase.guid))
+ mock_obj.assert_called_once_with(f'vmtp_{self.testcase.guid}')
args[0].assert_not_called()
diff --git a/functest/tests/unit/openstack/vping/test_vping_ssh.py b/functest/tests/unit/openstack/vping/test_vping_ssh.py
index 05482ed6b..a07148aab 100644
--- a/functest/tests/unit/openstack/vping/test_vping_ssh.py
+++ b/functest/tests/unit/openstack/vping/test_vping_ssh.py
@@ -47,7 +47,7 @@ class VpingSSHTesting(unittest.TestCase):
self.vping.prepare()
args[0].assert_called_once_with()
args[1].assert_called_once_with(
- '{}-vm2_{}'.format(self.vping.case_name, self.vping.guid),
+ f'{self.vping.case_name}-vm2_{self.vping.guid}',
security_groups=[self.vping.sec.id])
@mock.patch('functest.opnfv_tests.openstack.vping.vping_ssh.VPingSSH.'
@@ -58,27 +58,43 @@ class VpingSSHTesting(unittest.TestCase):
self.vping.prepare()
args[0].assert_called_once_with()
args[1].assert_called_once_with(
- '{}-vm2_{}'.format(self.vping.case_name, self.vping.guid),
+ f'{self.vping.case_name}-vm2_{self.vping.guid}',
security_groups=[self.vping.sec.id])
- def test_execute_exc(self):
- self.vping.vm2 = munch.Munch(private_v4='127.0.0.1')
+ @mock.patch('functest.opnfv_tests.openstack.vping.vping_ssh.VPingSSH.'
+ 'check_regex_in_console', return_value=True)
+ def test_execute_exc(self, *args):
+ self.vping.vm2 = munch.Munch(private_v4='127.0.0.1', name='foo')
self.vping.ssh = mock.Mock()
self.vping.ssh.exec_command.side_effect = ssh_exception.SSHException
with self.assertRaises(ssh_exception.SSHException):
self.vping.execute()
self.vping.ssh.exec_command.assert_called_once_with(
- 'ping -c 1 {}'.format(self.vping.vm2.private_v4))
+ f'ping -c 1 {self.vping.vm2.private_v4}')
+ args[0].assert_called_once_with('foo')
+
+ @mock.patch('functest.opnfv_tests.openstack.vping.vping_ssh.VPingSSH.'
+ 'check_regex_in_console', return_value=False)
+ def test_execute_exc2(self, *args):
+ self.vping.vm2 = munch.Munch(private_v4='127.0.0.1', name='foo')
+ self.vping.ssh = mock.Mock()
+ self.vping.execute()
+ self.vping.ssh.exec_command.assert_not_called()
+ args[0].assert_called_once_with('foo')
def _test_execute(self, ret=0):
- self.vping.vm2 = munch.Munch(private_v4='127.0.0.1')
+ self.vping.vm2 = munch.Munch(private_v4='127.0.0.1', name='foo')
self.vping.ssh = mock.Mock()
stdout = mock.Mock()
stdout.channel.recv_exit_status.return_value = ret
self.vping.ssh.exec_command.return_value = (None, stdout, mock.Mock())
- self.assertEqual(self.vping.execute(), ret)
+ with mock.patch(
+ 'functest.opnfv_tests.openstack.vping.vping_ssh.VPingSSH.'
+ 'check_regex_in_console', return_value=True) as mock_check:
+ self.assertEqual(self.vping.execute(), ret)
+ mock_check.assert_called_once_with('foo')
self.vping.ssh.exec_command.assert_called_once_with(
- 'ping -c 1 {}'.format(self.vping.vm2.private_v4))
+ f'ping -c 1 {self.vping.vm2.private_v4}')
def test_execute1(self):
self._test_execute()
diff --git a/functest/tests/unit/utils/test_functest_utils.py b/functest/tests/unit/utils/test_functest_utils.py
index dcbbd79e5..4b642ff9d 100644
--- a/functest/tests/unit/utils/test_functest_utils.py
+++ b/functest/tests/unit/utils/test_functest_utils.py
@@ -15,6 +15,7 @@ import unittest
import mock
import pkg_resources
+import six
from functest.utils import functest_utils
@@ -81,7 +82,7 @@ class FunctestUtilsTesting(unittest.TestCase):
def _get_environ(self, var, *args): # pylint: disable=unused-argument
if var == 'INSTALLER_TYPE':
return self.installer
- elif var == 'DEPLOY_SCENARIO':
+ if var == 'DEPLOY_SCENARIO':
return self.scenario
return var
@@ -97,27 +98,20 @@ class FunctestUtilsTesting(unittest.TestCase):
as mock_subproc_open, \
mock.patch('six.moves.builtins.open',
mock.mock_open()) as mopen:
-
- FunctestUtilsTesting.readline = 0
-
- mock_obj = mock.Mock()
- attrs = {'readline.side_effect': self.cmd_readline()}
- mock_obj.configure_mock(**attrs)
-
- mock_obj2 = mock.Mock()
- attrs = {'stdout': mock_obj, 'wait.return_value': 1}
- mock_obj2.configure_mock(**attrs)
-
- mock_subproc_open.return_value = mock_obj2
-
- resp = functest_utils.execute_command(self.cmd, info=True,
- error_msg=self.error_msg,
- verbose=True,
- output_file=self.output_file)
+ stream = six.BytesIO()
+ stream.write(self.cmd_readline().encode("utf-8"))
+ attrs = {
+ 'return_value.__enter__.return_value.stdout': stream,
+ 'return_value.__enter__.return_value.wait.return_value': 1}
+ mock_subproc_open.configure_mock(**attrs)
+ resp = functest_utils.execute_command(
+ self.cmd, info=True, error_msg=self.error_msg, verbose=True,
+ output_file=self.output_file)
self.assertEqual(resp, 1)
- msg_exec = ("Executing command: '%s'" % self.cmd)
+ msg_exec = f"Executing command: '{self.cmd}'"
mock_logger_info.assert_called_once_with(msg_exec)
- mopen.assert_called_once_with(self.output_file, "w")
+ mopen.assert_called_once_with(
+ self.output_file, "w", encoding='utf-8')
mock_logger_error.assert_called_once_with(self.error_msg)
@mock.patch('functest.utils.functest_utils.LOGGER.info')
@@ -126,50 +120,35 @@ class FunctestUtilsTesting(unittest.TestCase):
as mock_subproc_open, \
mock.patch('six.moves.builtins.open',
mock.mock_open()) as mopen:
-
- FunctestUtilsTesting.readline = 0
-
- mock_obj = mock.Mock()
- attrs = {'readline.side_effect': self.cmd_readline()}
- mock_obj.configure_mock(**attrs)
-
- mock_obj2 = mock.Mock()
- attrs = {'stdout': mock_obj, 'wait.return_value': 0}
- mock_obj2.configure_mock(**attrs)
-
- mock_subproc_open.return_value = mock_obj2
-
- resp = functest_utils.execute_command(self.cmd, info=True,
- error_msg=self.error_msg,
- verbose=True,
- output_file=self.output_file)
+ stream = six.BytesIO()
+ stream.write(self.cmd_readline().encode("utf-8"))
+ attrs = {
+ 'return_value.__enter__.return_value.stdout': stream,
+ 'return_value.__enter__.return_value.wait.return_value': 0}
+ mock_subproc_open.configure_mock(**attrs)
+ resp = functest_utils.execute_command(
+ self.cmd, info=True, error_msg=self.error_msg, verbose=True,
+ output_file=self.output_file)
self.assertEqual(resp, 0)
- msg_exec = ("Executing command: '%s'" % self.cmd)
+ msg_exec = (f"Executing command: '{self.cmd}'")
mock_logger_info.assert_called_once_with(msg_exec)
- mopen.assert_called_once_with(self.output_file, "w")
+ mopen.assert_called_once_with(
+ self.output_file, "w", encoding='utf-8')
@mock.patch('sys.stdout')
def test_exec_cmd_args_missing_ok(self, stdout=None):
# pylint: disable=unused-argument
with mock.patch('functest.utils.functest_utils.subprocess.Popen') \
as mock_subproc_open:
-
- FunctestUtilsTesting.readline = 2
-
- mock_obj = mock.Mock()
- attrs = {'readline.side_effect': self.cmd_readline()}
- mock_obj.configure_mock(**attrs)
-
- mock_obj2 = mock.Mock()
- attrs = {'stdout': mock_obj, 'wait.return_value': 0}
- mock_obj2.configure_mock(**attrs)
-
- mock_subproc_open.return_value = mock_obj2
-
- resp = functest_utils.execute_command(self.cmd, info=False,
- error_msg="",
- verbose=False,
- output_file=None)
+ stream = six.BytesIO()
+ stream.write(self.cmd_readline().encode("utf-8"))
+ attrs = {
+ 'return_value.__enter__.return_value.stdout': stream,
+ 'return_value.__enter__.return_value.wait.return_value': 0}
+ mock_subproc_open.configure_mock(**attrs)
+ resp = functest_utils.execute_command(
+ self.cmd, info=False, error_msg="", verbose=False,
+ output_file=None)
self.assertEqual(resp, 0)
@mock.patch('sys.stdout')
@@ -177,22 +156,16 @@ class FunctestUtilsTesting(unittest.TestCase):
# pylint: disable=unused-argument
with mock.patch('functest.utils.functest_utils.subprocess.Popen') \
as mock_subproc_open:
-
- FunctestUtilsTesting.readline = 2
- mock_obj = mock.Mock()
- attrs = {'readline.side_effect': self.cmd_readline()}
- mock_obj.configure_mock(**attrs)
-
- mock_obj2 = mock.Mock()
- attrs = {'stdout': mock_obj, 'wait.return_value': 1}
- mock_obj2.configure_mock(**attrs)
-
- mock_subproc_open.return_value = mock_obj2
-
- resp = functest_utils.execute_command(self.cmd, info=False,
- error_msg="",
- verbose=False,
- output_file=None)
+ attrs = {}
+ stream = six.BytesIO()
+ stream.write(self.cmd_readline().encode("utf-8"))
+ attrs = {
+ 'return_value.__enter__.return_value.stdout': stream,
+ 'return_value.__enter__.return_value.wait.return_value': 1}
+ mock_subproc_open.configure_mock(**attrs)
+ resp = functest_utils.execute_command(
+ self.cmd, info=False, error_msg="", verbose=False,
+ output_file=None)
self.assertEqual(resp, 1)
def test_get_param_from_yaml_failed(self):
@@ -204,9 +177,9 @@ class FunctestUtilsTesting(unittest.TestCase):
mock_yaml.return_value = self.file_yaml
functest_utils.get_parameter_from_yaml(self.parameter,
self.test_file)
- self.assertTrue(("The parameter %s is not"
- " defined in config_functest.yaml" %
- self.parameter) in excep.exception)
+ self.assertTrue((f"The parameter {self.parameter} is not"
+ " defined in config_functest.yaml"
+ ) in excep.exception)
def test_get_param_from_yaml_def(self):
with mock.patch('six.moves.builtins.open', mock.mock_open()), \
@@ -331,6 +304,54 @@ class FunctestUtilsTesting(unittest.TestCase):
args[0].assert_called_once_with(cloud)
@mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 66))
+ def test_openstack_version11(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(
+ cloud), "Stein")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 78))
+ def test_openstack_version12(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(
+ cloud), "Train")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 87))
+ def test_openstack_version13(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(
+ cloud), "Ussuri")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 88))
+ def test_openstack_version14(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(
+ cloud), "Wallaby")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 89))
+ def test_openstack_version15(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(
+ cloud), "Xena")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 92))
+ def test_openstack_version16(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(
+ cloud), "Zed")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
return_value=None)
def test_openstack_version_exc(self, *args):
cloud = mock.Mock()
@@ -344,7 +365,7 @@ class FunctestUtilsTesting(unittest.TestCase):
self.assertEqual(
functest_utils.convert_dict_to_ini({"a": "b"}), "a:b")
value = functest_utils.convert_dict_to_ini({"a": "b", "c": "d"})
- self.assertTrue(value == "a:b,c:d" or value == "c:d,a:b")
+ self.assertTrue(value in ('a:b,c:d', 'c:d,a:b'))
with self.assertRaises(AssertionError):
functest_utils.convert_list_to_ini("")
diff --git a/functest/tests/unit/vnf/epc/test_juju_epc.py b/functest/tests/unit/vnf/epc/test_juju_epc.py
index 6b4137069..a72c61586 100644
--- a/functest/tests/unit/vnf/epc/test_juju_epc.py
+++ b/functest/tests/unit/vnf/epc/test_juju_epc.py
@@ -62,7 +62,6 @@ class JujuEpcTesting(unittest.TestCase):
'test_vnf': {}}
@unittest.skip("It must be fixed. Please see JIRA FUNCTEST-915")
- @mock.patch('snaps.openstack.create_image.OpenStackImage.create')
@mock.patch('os.system')
def test_prepare_default(self, *args):
""" Unittest for Prepare testcase """
diff --git a/functest/tests/unit/vnf/ims/test_clearwater.py b/functest/tests/unit/vnf/ims/test_clearwater.py
index 93f8ffe4a..f590a2857 100644
--- a/functest/tests/unit/vnf/ims/test_clearwater.py
+++ b/functest/tests/unit/vnf/ims/test_clearwater.py
@@ -20,7 +20,8 @@ class ClearwaterTesting(unittest.TestCase):
def setUp(self):
with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
'os.makedirs'):
- self.ims_vnf = clearwater.ClearwaterTesting("foo", "0.0.0.0")
+ self.ims_vnf = clearwater.ClearwaterTesting(
+ "foo", "0.0.0.0", "0.0.0.0")
self.mock_post = mock.Mock()
attrs = {'status_code': 201,
@@ -37,6 +38,7 @@ class ClearwaterTesting(unittest.TestCase):
'cookies': ""}
self.mock_post_200.configure_mock(**attrs)
+
if __name__ == "__main__":
logging.disable(logging.CRITICAL)
unittest.main(verbosity=2)
diff --git a/functest/utils/config.py b/functest/utils/config.py
index 61d8401c5..40414b88b 100644
--- a/functest/utils/config.py
+++ b/functest/utils/config.py
@@ -10,15 +10,16 @@ import six
from functest.utils import env
-class Config(object):
+class Config():
def __init__(self):
try:
- # pylint: disable=bad-continuation
with open(pkg_resources.resource_filename(
- 'functest', 'ci/config_functest.yaml')) as yfile:
+ 'functest', 'ci/config_functest.yaml'),
+ encoding='utf-8') as yfile:
self.functest_yaml = yaml.safe_load(yfile)
except Exception as error:
- raise Exception('Parse config failed: {}'.format(str(error)))
+ raise Exception(
+ f'Parse config failed: {str(error)}') from error
@staticmethod
def _merge_dicts(dict1, dict2):
@@ -34,7 +35,7 @@ class Config(object):
yield (k, dict2[k])
def patch_file(self, patch_file_path):
- with open(patch_file_path) as yfile:
+ with open(patch_file_path, encoding='utf-8') as yfile:
patch_file = yaml.safe_load(yfile)
for key in patch_file:
@@ -53,13 +54,14 @@ class Config(object):
@staticmethod
def _get_attr_further(attr_now, next): # pylint: disable=redefined-builtin
return attr_now if next == 'general' else (
- '{}_{}'.format(attr_now, next) if attr_now else next)
+ f'{attr_now}_{next}' if attr_now else next)
def fill(self):
try:
self._parse(None, self.functest_yaml)
except Exception as error:
- raise Exception('Parse config failed: {}'.format(str(error)))
+ raise Exception(
+ f'Parse config failed: {str(error)}') from error
CONF = Config()
diff --git a/functest/utils/env.py b/functest/utils/env.py
index 41d1a4d86..2e312726c 100644
--- a/functest/utils/env.py
+++ b/functest/utils/env.py
@@ -17,6 +17,7 @@ from xtesting.utils import env
INPUTS = {
'EXTERNAL_NETWORK': None,
'CI_LOOP': env.INPUTS['CI_LOOP'],
+ 'DEBUG': env.INPUTS['DEBUG'],
'DEPLOY_SCENARIO': env.INPUTS['DEPLOY_SCENARIO'],
'INSTALLER_TYPE': env.INPUTS['INSTALLER_TYPE'],
'SDN_CONTROLLER_IP': None,
@@ -28,16 +29,19 @@ INPUTS = {
'NODE_NAME': env.INPUTS['NODE_NAME'],
'POD_ARCH': None,
'TEST_DB_URL': env.INPUTS['TEST_DB_URL'],
- 'ENERGY_RECORDER_API_URL': env.INPUTS['ENERGY_RECORDER_API_URL'],
- 'ENERGY_RECORDER_API_USER': env.INPUTS['ENERGY_RECORDER_API_USER'],
- 'ENERGY_RECORDER_API_PASSWORD': env.INPUTS['ENERGY_RECORDER_API_PASSWORD'],
'VOLUME_DEVICE_NAME': 'vdb',
'IMAGE_PROPERTIES': '',
'FLAVOR_EXTRA_SPECS': '',
'NAMESERVER': '8.8.8.8',
'NEW_USER_ROLE': 'Member',
'USE_DYNAMIC_CREDENTIALS': 'True',
- 'STORAGE_PROTOCOL': 'iSCSI'
+ 'BLOCK_MIGRATION': 'False',
+ 'CLEAN_ORPHAN_SECURITY_GROUPS': 'True',
+ 'SKIP_DOWN_HYPERVISORS': 'False',
+ 'PUBLIC_ENDPOINT_ONLY': 'False',
+ 'DASHBOARD_URL': '',
+ 'VMTP_HYPERVISORS': '',
+ 'NO_TENANT_NETWORK': 'False'
}
diff --git a/functest/utils/functest_utils.py b/functest/utils/functest_utils.py
index b49337de2..eec544489 100644
--- a/functest/utils/functest_utils.py
+++ b/functest/utils/functest_utils.py
@@ -11,10 +11,12 @@
from __future__ import print_function
import logging
+import os
import subprocess
import sys
import yaml
+from shade import _utils
import six
LOGGER = logging.getLogger(__name__)
@@ -30,28 +32,26 @@ def execute_command_raise(cmd, info=False, error_msg="",
def execute_command(cmd, info=False, error_msg="",
verbose=True, output_file=None):
if not error_msg:
- error_msg = ("The command '%s' failed." % cmd)
- msg_exec = ("Executing command: '%s'" % cmd)
+ error_msg = f"The command '{cmd}' failed."
+ msg_exec = f"Executing command: '{cmd}'"
if verbose:
if info:
LOGGER.info(msg_exec)
else:
LOGGER.debug(msg_exec)
- popen = subprocess.Popen(
- cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- if output_file:
- ofd = open(output_file, "w")
- for line in iter(popen.stdout.readline, b''):
+ with subprocess.Popen(
+ cmd, shell=True, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT) as popen:
if output_file:
- ofd.write(line)
- else:
- line = line.replace('\n', '')
- print(line)
- sys.stdout.flush()
- if output_file:
- ofd.close()
- popen.stdout.close()
- returncode = popen.wait()
+ with open(output_file, "w", encoding='utf-8') as ofd:
+ for line in iter(popen.stdout.readline, b''):
+ if output_file:
+ ofd.write(line.decode("utf-8"))
+ else:
+ line = line.decode("utf-8").replace('\n', '')
+ print(line)
+ sys.stdout.flush()
+ returncode = popen.wait()
if returncode != 0:
if verbose:
LOGGER.error(error_msg)
@@ -65,14 +65,14 @@ def get_parameter_from_yaml(parameter, yfile):
parameter must be given in string format with dots
Example: general.openstack.image_name
"""
- with open(yfile) as yfd:
+ with open(yfile, encoding='utf-8') as yfd:
file_yaml = yaml.safe_load(yfd)
value = file_yaml
for element in parameter.split("."):
value = value.get(element)
if value is None:
- raise ValueError("The parameter %s is not defined in"
- " %s" % (parameter, yfile))
+ raise ValueError(f"The parameter {parameter} is not defined in"
+ f" {yfile}")
return value
@@ -108,11 +108,24 @@ def get_openstack_version(cloud):
- OpenStack release
- Unknown on operation error
"""
+ # pylint: disable=too-many-branches
version = get_nova_version(cloud)
try:
assert version
- if version > (2, 65):
+ if version > (2, 93):
osversion = "Master"
+ elif version > (2, 90):
+ osversion = "Zed"
+ elif version > (2, 88):
+ osversion = "Xena"
+ elif version > (2, 87):
+ osversion = "Wallaby"
+ elif version > (2, 79):
+ osversion = "Ussuri"
+ elif version > (2, 72):
+ osversion = "Train"
+ elif version > (2, 65):
+ osversion = "Stein"
elif version > (2, 60):
osversion = "Rocky"
elif version > (2, 53):
@@ -138,24 +151,68 @@ def get_openstack_version(cloud):
return "Unknown"
+def list_services(cloud):
+ # pylint: disable=protected-access
+ """Search Keystone services via $OS_INTERFACE.
+
+ It mainly conforms with `Shade
+ <https://docs.openstack.org/shade/latest>`_ but allows testing vs
+ public endpoints. It's worth mentioning that it doesn't support keystone
+ v2.
+
+ :returns: a list of ``munch.Munch`` containing the services description
+
+ :raises: ``OpenStackCloudException`` if something goes wrong during the
+ openstack API call.
+ """
+ url, key = '/services', 'services'
+ data = cloud._identity_client.get(
+ url, endpoint_filter={
+ 'interface': os.environ.get('OS_INTERFACE', 'public')},
+ error_message="Failed to list services")
+ services = cloud._get_and_munchify(key, data)
+ return _utils.normalize_keystone_services(services)
+
+
+def search_services(cloud, name_or_id=None, filters=None):
+ # pylint: disable=protected-access
+ """Search Keystone services ia $OS_INTERFACE.
+
+ It mainly conforms with `Shade
+ <https://docs.openstack.org/shade/latest>`_ but allows testing vs
+ public endpoints. It's worth mentioning that it doesn't support keystone
+ v2.
+
+ :param name_or_id: Name or id of the desired service.
+ :param filters: a dict containing additional filters to use. e.g.
+ {'type': 'network'}.
+
+ :returns: a list of ``munch.Munch`` containing the services description
+
+ :raises: ``OpenStackCloudException`` if something goes wrong during the
+ openstack API call.
+ """
+ services = list_services(cloud)
+ return _utils._filter_list(services, name_or_id, filters)
+
+
def convert_dict_to_ini(value):
"Convert dict to oslo.conf input"
assert isinstance(value, dict)
- return ",".join("{}:{}".format(
- key, val) for (key, val) in six.iteritems(value))
+ return ",".join(f"{key}:{val}" for (key, val) in six.iteritems(value))
def convert_list_to_ini(value):
"Convert list to oslo.conf input"
assert isinstance(value, list)
- return ",".join("{}".format(val) for val in value)
+ return ",".join(val for val in value)
def convert_ini_to_dict(value):
"Convert oslo.conf input to dict"
assert isinstance(value, str)
try:
- return {k: v for k, v in (x.rsplit(':', 1) for x in value.split(','))}
+ return dict((x.rsplit(':', 1) for x in value.split(',')))
except ValueError:
return {}
@@ -165,4 +222,4 @@ def convert_ini_to_list(value):
assert isinstance(value, str)
if not value:
return []
- return [x for x in value.split(',')]
+ return list(value.split(','))
diff --git a/requirements.txt b/requirements.txt
index 298cc38ad..385f8d8e6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,17 +3,20 @@
# process, which may cause wedges in the gate later.
pbr!=2.1.0 # Apache-2.0
PyYAML # MIT
-requests # Apache-2.0
+requests!=2.20.0,!=2.24.0 # Apache-2.0
robotframework>=3.0
scp
cloudify-rest-client
-mock # BSD
-PrettyTable<0.8 # BSD
+mock!=4.0.0,!=4.0.1 # BSD
+PrettyTable!=3.4.0 # BSD
six # MIT
-snaps
-paramiko # LGPLv2.1+
+paramiko!=2.9.0,!=2.9.1 # LGPLv2.1+
Jinja2 # BSD License (3 clause)
xtesting
os-client-config # Apache-2.0
shade # Apache-2.0
ruamel.yaml.jinja2 # MIT
+tempest # Apache-2.0
+rally
+rally-openstack
+munch # MIT
diff --git a/rtd-requirements.txt b/rtd-requirements.txt
deleted file mode 100644
index feba192d4..000000000
--- a/rtd-requirements.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-git+https://gerrit.opnfv.org/gerrit/snaps#egg=snaps
--r requirements.txt
--r test-requirements.txt
diff --git a/setup.cfg b/setup.cfg
index 954dcaa9a..3b466985a 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = functest
-version = 7
+version = 10
home-page = https://wiki.opnfv.org/display/functest
[files]
@@ -13,7 +13,6 @@ scripts =
[entry_points]
console_scripts =
functest_odl = functest.opnfv_tests.sdn.odl.odl:main
- check_deployment = functest.ci.check_deployment:main
xtesting.testcase =
connection_check = functest.opnfv_tests.openstack.api.connection_check:ConnectionCheck
tenantnetwork1 = functest.core.tenantnetwork:TenantNetwork1
@@ -26,17 +25,14 @@ xtesting.testcase =
vping_userdata = functest.opnfv_tests.openstack.vping.vping_userdata:VPingUserdata
cinder_test = functest.opnfv_tests.openstack.cinder.cinder_test:CinderCheck
odl = functest.opnfv_tests.sdn.odl.odl:ODLTests
- api_check = functest.opnfv_tests.openstack.snaps.api_check:ApiCheck
- snaps_health_check = functest.opnfv_tests.openstack.snaps.health_check:HealthCheck
tempest_common = functest.opnfv_tests.openstack.tempest.tempest:TempestCommon
+ tempest_heat = functest.opnfv_tests.openstack.tempest.tempest:TempestHeat
rally_sanity = functest.opnfv_tests.openstack.rally.rally:RallySanity
- refstack_defcore = functest.opnfv_tests.openstack.refstack.refstack:Refstack
+ refstack = functest.opnfv_tests.openstack.refstack.refstack:Refstack
patrole = functest.opnfv_tests.openstack.patrole.patrole:Patrole
barbican = functest.opnfv_tests.openstack.barbican.barbican:Barbican
vmtp = functest.opnfv_tests.openstack.vmtp.vmtp:Vmtp
shaker = functest.opnfv_tests.openstack.shaker.shaker:Shaker
- snaps_smoke = functest.opnfv_tests.openstack.snaps.smoke:SnapsSmoke
- vgpu = functest.opnfv_tests.openstack.vgpu.vgpu:vGPU
rally_full = functest.opnfv_tests.openstack.rally.rally:RallyFull
cloudify = functest.core.cloudify:Cloudify
cloudify_ims = functest.opnfv_tests.vnf.ims.cloudify_ims:CloudifyIms
diff --git a/setup.py b/setup.py
index 566d84432..f63cc23c5 100644
--- a/setup.py
+++ b/setup.py
@@ -16,14 +16,6 @@
# 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
index b071f41e0..03f57b9cc 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -2,15 +2,17 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
coverage!=4.4 # Apache-2.0
-mock # BSD
-nose # LGPL
-flake8<2.6.0,>=2.5.4 # MIT
+mock!=4.0.0,!=4.0.1 # BSD
+pytest # MIT
+pytest-html #MPL-2.0
+pytest-cov # MIT
+flake8 # MIT
pylint # GPLv2
-sphinx!=1.6.6,!=1.6.7 # BSD
+sphinx!=1.6.6,!=1.6.7,!=2.1.0,!=3.0.0,!=3.4.2 # BSD
sphinx-rtd-theme
yamllint
doc8 # Apache-2.0
bashate # Apache-2.0
-nosehtmloutput # Apache-2.0
-lfdocs-conf
-sphinx-opnfv-theme
+bandit
+sphinxcontrib-spelling
+pre-commit
diff --git a/tox.ini b/tox.ini
index 556a09a23..1bebeb93a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,25 +1,23 @@
[tox]
-envlist = docs,pep8,pylint,yamllint,bashate,py27,perm,cover
+envlist = docs,pep8,pylint,yamllint,bashate,bandit,py310,cover,perm,pre-commit
[testenv]
usedevelop = True
deps =
-c{toxinidir}/upper-constraints.txt
- -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=master}
+ -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/branch/master/upper-constraints.txt}
-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
-install_command = pip install {opts} {packages}
-commands = nosetests --with-xunit \
- --with-coverage \
- --cover-tests \
- --cover-package=functest \
- --cover-xml \
- --cover-html \
- --with-html-output \
- functest/tests/unit
+install_command = pip install --use-deprecated=legacy-resolver {opts} {packages}
+commands =
+ pytest \
+ --junit-xml=junit.xml \
+ --html=report.html --self-contained-html \
+ --cov=xtesting --cov-reset --cov-report html \
+ functest/tests/unit
[testenv:docs]
-basepython = python2.7
+basepython = python3.10
commands =
doc8 \
--ignore-path api/build \
@@ -29,73 +27,37 @@ commands =
docs
sphinx-build -W -b html api/ api/build
sphinx-build -W -n -b html docs docs/build/html
- sphinx-build -W -n -b linkcheck docs docs/_build/linkcheck
- sphinx-build -W -n -b html -c docs/lfreleng docs docs/_build/html
+ sphinx-build -W -n -b linkcheck docs docs/build/linkcheck
+ sphinx-build -W -b spelling -Dextensions=sphinxcontrib.spelling docs docs/build/spellcheck
[testenv:pep8]
-basepython = python2.7
+basepython = python3.10
commands = flake8
[testenv:pylint]
-basepython = python2.7
-whitelist_externals = bash
-modules =
- functest.ci
- functest.opnfv_tests.openstack.cinder
- functest.opnfv_tests.openstack.rally
- functest.opnfv_tests.openstack.refstack
- functest.opnfv_tests.openstack.snaps
- functest.opnfv_tests.openstack.tempest
- functest.opnfv_tests.openstack.vmtp
- functest.opnfv_tests.openstack.vping
- functest.opnfv_tests.sdn.odl
- functest.opnfv_tests.vnf.router
- functest.tests.unit.ci
- functest.tests.unit.odl
- functest.tests.unit.openstack.rally
- functest.tests.unit.openstack.snaps
- functest.tests.unit.openstack.tempest
- functest.tests.unit.openstack.vmtp
- functest.tests.unit.openstack.vping
- functest.tests.unit.vnf.router
- functest.tests.unit.utils
- functest.utils.config
- functest.utils.constants
- functest.utils.env
- functest.utils.functest_utils
+basepython = python3.10
commands =
- bash -c "\
- pylint -f parseable \
- --ignore-imports=y \
- --disable=locally-disabled functest | tee pylint.out"
- pylint --reports=n --errors-only functest
- pylint --disable=locally-disabled \
- --disable=duplicate-code \
- --ignore-imports=y --reports=n {[testenv:pylint]modules}
+ pylint \
+ --ignore-imports=y --min-similarity-lines=15 \
+ --generated-members=os.* \
+ --disable=locally-disabled functest
[testenv:yamllint]
-basepython = python2.7
+basepython = python3.10
files =
.travis.yml
- ci
docker
functest/ci
+ functest/opnfv_tests/openstack/rally/blacklist.yaml
functest/opnfv_tests/openstack/rally/rally_jobs.yaml
+ functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml
+ functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml
functest/opnfv_tests/vnf
commands =
yamllint -s {[testenv:yamllint]files}
-[testenv:py36]
-dirs =
- functest/tests/unit/ci
- functest/tests/unit/odl
- functest/tests/unit/openstack
- functest/tests/unit/vnf/epc
- functest/tests/unit/utils
-commands = nosetests {[testenv:py36]dirs}
-
[testenv:bashate]
-basepython = python2.7
+basepython = python3.10
files =
functest/opnfv_tests/openstack/cinder/write_data.sh
functest/opnfv_tests/openstack/cinder/read_data.sh
@@ -103,30 +65,34 @@ files =
functest/ci/convert_images.sh
functest/ci/download_images.sh
build.sh
-commands = bashate {[testenv:bashate]files}
+commands = bashate -e E005,E006,E042,E043 {[testenv:bashate]files}
+
+[testenv:bandit]
+basepython = python3.10
+commands = bandit -r functest -x tests -n 5 -ll -s B601,B602
[testenv:cover]
-basepython = python2.7
+basepython = python3.10
dirs =
- functest/tests/unit/ci
functest/tests/unit/odl
functest/tests/unit/openstack/vping
functest/tests/unit/openstack/cinder
-commands = nosetests --with-coverage --cover-tests \
- --cover-package functest.ci.check_deployment \
- --cover-package functest.opnfv_tests.sdn.odl \
- --cover-package functest.opnfv_tests.openstack.vping.vping_ssh \
- --cover-package functest.opnfv_tests.openstack.cinder.cinder_test \
- --cover-package functest.tests.unit \
- --cover-min-percentage 100 {[testenv:cover]dirs}
+commands =
+ pytest --cov=xtesting --cov-reset --cov-report html --cov-fail-under=100 \
+ {[testenv:cover]dirs}
[testenv:perm]
-basepython = python2.7
-whitelist_externals = bash
-path=. -not -path './.tox/*' -not -path './.git/*' -not -path './docs/com/pres/reveal.js/*'
+basepython = python3.10
+allowlist_externals = sh
+path=. -not -path './.tox/*' -not -path './.git/*' -not -path './docs/com/pres/reveal.js/*' -not -path './elements/functest/install.d/*'
commands =
- bash -c "\
+ sh -c "\
find {[testenv:perm]path} \( -type f -not -perm 644 -o -type d -not -perm 755 \) \
-exec ls -l \{\} + | grep '.' && exit 1 || exit 0"
- bash -c "\
+ sh -c "\
find {[testenv:perm]path} -exec file \{\} + | grep CRLF && exit 1 || exit 0"
+
+[testenv:pre-commit]
+basepython = python3.10
+commands =
+ pre-commit run --all-files --show-diff-on-failure
diff --git a/upper-constraints.txt b/upper-constraints.txt
index 16200d0b7..5eff3d20f 100644
--- a/upper-constraints.txt
+++ b/upper-constraints.txt
@@ -1,21 +1,24 @@
git+https://gerrit.opnfv.org/gerrit/functest#egg=functest
-git+https://gerrit.opnfv.org/gerrit/releng#egg=opnfv&subdirectory=modules
-git+https://gerrit.opnfv.org/gerrit/snaps@0dacfaa2fbd2dfe7fc9d438b9350a0187506e61c#egg=snaps
-git+https://gerrit.opnfv.org/gerrit/barometer#egg=baro_tests
-git+https://gerrit.opnfv.org/gerrit/sdnvpn#egg=sdnvpn
-git+https://gerrit.opnfv.org/gerrit/sfc#egg=sfc
--e git+https://gerrit.opnfv.org/gerrit/doctor#egg=doctor-tests
-git+https://gerrit.opnfv.org/gerrit/stor4nfv#egg=stor4nfv-tests
-git+https://gerrit.opnfv.org/gerrit/clover#egg=clover
-git+https://gerrit.opnfv.org/gerrit/parser#egg=nfv-heattranslator&subdirectory=tosca2heat/heat-translator
-git+https://gerrit.opnfv.org/gerrit/parser#egg=nfv-toscaparser&subdirectory=tosca2heat/tosca-parser
--e git+https://gerrit.opnfv.org/gerrit/parser#egg=nfv-parser
-cloudify-rest-client===4.3.2
-robotframework===3.0.2
+git+https://github.com/collivier/cloudify-rest-client.git@4.3.3-py3#egg=cloudify-rest-client
+robotframework===4.1.2
robotframework-httplibrary===0.4.2
-robotframework-requests===0.4.7
-robotframework-sshlibrary===2.1.3;python_version=='2.7'
-ansible===2.3.2.0
-xtesting===0.60.0
-git+https://git.openstack.org/openstack/networking-bgpvpn#egg=networking_bgpvpn
-git+https://git.openstack.org/openstack/networking-sfc#egg=networking_sfc
+robotframework-requests===0.9.2
+robotframework-sshlibrary===3.8.0
+xtesting===0.98.0
+bandit===1.7.5
+bandit===1.7.0
+ruamel.yaml.jinja2==0.2.2
+-e git+https://opendev.org/openstack/tempest#egg=tempest
+-e git+https://opendev.org/openstack/rally.git#egg=rally
+git+https://opendev.org/openstack/rally-openstack.git#egg=rally-openstack
+git+https://github.com/xrally/xrally-kubernetes.git#egg=xrally-kubernetes
+pylint===2.11.1
+flake8===4.0.1
+pytest===7.1.2
+pytest-cov===3.0.0
+pytest-html===3.1.1
+ruamel.yaml===0.17.17
+sphinxcontrib-spelling===4.3.0
+ansible-lint===5.2.1
+setuptools_scm===6.3.2
+pre-commit===3.1.1