summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.coveragerc3
-rw-r--r--INFO2
-rw-r--r--docker/Dockerfile15
-rwxr-xr-xfunctest/ci/check_os.sh2
-rwxr-xr-xfunctest/ci/config_functest.yaml182
-rwxr-xr-xfunctest/ci/exec_test.sh17
-rwxr-xr-xfunctest/ci/generate_report.py54
-rwxr-xr-xfunctest/ci/prepare_env.py185
-rwxr-xr-xfunctest/ci/run_tests.py107
-rwxr-xr-xfunctest/ci/testcases.yaml85
-rw-r--r--functest/cli/cli_base.py14
-rw-r--r--functest/cli/commands/cli_env.py72
-rw-r--r--functest/cli/commands/cli_os.py45
-rw-r--r--functest/cli/commands/cli_testcase.py30
-rw-r--r--functest/cli/commands/cli_tier.py29
-rw-r--r--functest/core/feature_base.py10
-rw-r--r--functest/core/testcase_base.py47
-rw-r--r--functest/core/vnf_base.py248
-rwxr-xr-xfunctest/opnfv_tests/features/copper.py2
-rwxr-xr-xfunctest/opnfv_tests/features/domino.py65
-rw-r--r--functest/opnfv_tests/features/odl_sfc.py4
-rwxr-xr-xfunctest/opnfv_tests/features/sdnvpn.py70
-rwxr-xr-xfunctest/opnfv_tests/mano/orchestra.py24
-rwxr-xr-xfunctest/opnfv_tests/openstack/examples/create_instance_and_ip.py28
-rwxr-xr-xfunctest/opnfv_tests/openstack/healthcheck/healthcheck.sh5
-rwxr-xr-xfunctest/opnfv_tests/openstack/rally/run_rally-cert.py70
-rw-r--r--functest/opnfv_tests/openstack/snaps/api_check.py18
-rw-r--r--functest/opnfv_tests/openstack/snaps/connection_check.py18
-rw-r--r--functest/opnfv_tests/openstack/snaps/smoke.py22
-rw-r--r--functest/opnfv_tests/openstack/snaps/snaps_utils.py5
-rw-r--r--functest/opnfv_tests/openstack/tempest/conf_utils.py86
-rw-r--r--functest/opnfv_tests/openstack/tempest/tempest.py304
-rw-r--r--functest/opnfv_tests/openstack/vping/vping_base.py45
-rwxr-xr-xfunctest/opnfv_tests/sdn/odl/odl.py91
-rwxr-xr-xfunctest/opnfv_tests/sdn/onos/teston/onos.py16
-rw-r--r--functest/opnfv_tests/vnf/aaa/__init__.py0
-rw-r--r--functest/opnfv_tests/vnf/aaa/aaa.py70
-rw-r--r--functest/opnfv_tests/vnf/ims/__init__.py0
-rw-r--r--functest/opnfv_tests/vnf/ims/cloudify_ims.py278
-rw-r--r--functest/opnfv_tests/vnf/ims/opera_ims.py155
-rw-r--r--functest/opnfv_tests/vnf/ims/orchestra_ims.py157
-rw-r--r--functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py (renamed from functest/opnfv_tests/vnf/ims/orchestrator.py)0
-rwxr-xr-xfunctest/opnfv_tests/vnf/ims/vims.py521
-rw-r--r--functest/tests/unit/cli/__init__.py0
-rw-r--r--functest/tests/unit/cli/commands/__init__.py0
-rw-r--r--functest/tests/unit/cli/commands/test_cli_env.py131
-rw-r--r--functest/tests/unit/cli/commands/test_cli_os.py238
-rw-r--r--functest/tests/unit/cli/commands/test_cli_testcase.py103
-rw-r--r--functest/tests/unit/cli/commands/test_cli_tier.py130
-rw-r--r--functest/tests/unit/cli/test_cli_base.py138
-rw-r--r--functest/tests/unit/core/test_testcase_base.py10
-rw-r--r--functest/tests/unit/core/test_vnf_base.py52
-rw-r--r--functest/tests/unit/odl/test_odl.py160
-rw-r--r--functest/tests/unit/test_utils.py23
-rw-r--r--functest/tests/unit/utils/test_functest_utils.py600
-rw-r--r--functest/tests/unit/utils/test_openstack_clean.py671
-rw-r--r--functest/tests/unit/utils/test_openstack_snapshot.py235
-rw-r--r--functest/tests/unit/utils/test_openstack_tacker.py455
-rw-r--r--functest/tests/unit/utils/test_openstack_utils.py1688
-rw-r--r--functest/tests/unit/utils/test_utils.py45
-rw-r--r--functest/utils/config.py15
-rw-r--r--functest/utils/env.py25
-rw-r--r--functest/utils/functest_constants.py93
-rw-r--r--functest/utils/functest_logger.py2
-rw-r--r--functest/utils/functest_utils.py59
-rwxr-xr-xfunctest/utils/openstack_clean.py16
-rwxr-xr-xfunctest/utils/openstack_snapshot.py9
-rwxr-xr-xfunctest/utils/openstack_utils.py96
-rwxr-xr-xrun_unit_tests.sh33
-rw-r--r--test-requirements.txt4
70 files changed, 6679 insertions, 1553 deletions
diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 000000000..fe258c6c6
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,3 @@
+[report]
+exclude_lines =
+ if __name__ == .__main__.:
diff --git a/INFO b/INFO
index 07145bd13..6f8963e76 100644
--- a/INFO
+++ b/INFO
@@ -12,7 +12,7 @@ Repository: functest
Committers:
yaohelan@huawei.com
-serena.feng.711@gmail.com
+feng.xiaowei@zte.com.cn
ollivier.cedric@gmail.com
jose.lausuch@ericsson.com
morgan.richomme@orange.com
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 5105fbbd1..dce657e8e 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -31,7 +31,6 @@ LABEL version="0.1" description="OPNFV Functest Docker container"
# Environment variables
ARG BRANCH=master
ARG TEMPEST_TAG=12.2.0
-ARG RALLY_TAG=0.7.0
ARG ODL_TAG=release/beryllium-sr4
ARG OPENSTACK_TAG=stable/mitaka
ARG KINGBIRD_TAG=0.2.2
@@ -44,6 +43,7 @@ ARG FUNCTEST_RESULTS_DIR=${FUNCTEST_BASE_DIR}/results
ARG FUNCTEST_REPO_DIR=${REPOS_DIR}/functest
ARG FUNCTEST_TEST_DIR=${FUNCTEST_REPO_DIR}/functest/opnfv_tests
ARG RELENG_MODULE_DIR=${REPOS_DIR}/releng/modules
+ARG REPOS_VNFS_DIR=${REPOS_DIR}/vnfs
# Environment variables
ENV HOME /home/opnfv
@@ -82,6 +82,7 @@ wget \
RUN pip install --upgrade pip
RUN mkdir -p ${REPOS_DIR} \
+ && mkdir -p ${REPOS_VNFS_DIR} \
&& mkdir -p ${FUNCTEST_BASE_DIR}/results \
&& mkdir -p ${FUNCTEST_BASE_DIR}/conf \
&& mkdir -p /root/.ssh \
@@ -106,12 +107,12 @@ RUN git clone --depth 1 https://gerrit.opnfv.org/gerrit/releng ${REPOS_DIR}/rele
# OpenStack repositories
RUN git clone --depth 1 -b $OPENSTACK_TAG https://github.com/openstack/networking-bgpvpn ${REPOS_DIR}/bgpvpn
#RUN git clone --depth 1 -b $KINGBIRD_TAG https://github.com/openstack/kingbird.git ${REPOS_DIR}/kingbird
-RUN git clone --depth 1 -b $RALLY_TAG https://github.com/openstack/rally.git ${REPOS_DIR}/rally
+RUN git clone https://github.com/openstack/rally.git ${REPOS_DIR}/rally
RUN git clone --depth 1 -b $TEMPEST_TAG https://github.com/openstack/tempest.git ${REPOS_DIR}/tempest
# other repositories
RUN git clone --depth 1 -b $ODL_TAG https://git.opendaylight.org/gerrit/p/integration/test.git ${REPOS_DIR}/odl_test
-RUN git clone --depth 1 -b $VIMS_TAG https://github.com/boucherv-orange/clearwater-live-test ${REPOS_DIR}/vims-test
+RUN git clone --depth 1 -b $VIMS_TAG https://github.com/boucherv-orange/clearwater-live-test ${REPOS_VNFS_DIR}/vims-test
RUN git clone --depth 1 https://github.com/wuwenbin2/OnosSystemTest.git ${REPOS_DIR}/onos
RUN cd ${FUNCTEST_REPO_DIR} \
@@ -154,16 +155,16 @@ RUN cd ${REPOS_DIR}/bgpvpn && pip install .
RUN cd ${REPOS_DIR}/moon/moonclient/ && python setup.py install
RUN /bin/bash -c ". /etc/profile.d/rvm.sh \
- && cd ${REPOS_DIR}/vims-test \
+ && cd ${REPOS_VNFS_DIR}/vims-test \
&& rvm autolibs enable"
RUN /bin/bash -c ". /etc/profile.d/rvm.sh \
- && cd ${REPOS_DIR}/vims-test \
+ && cd ${REPOS_VNFS_DIR}/vims-test \
&& rvm install 1.9.3"
RUN /bin/bash -c ". /etc/profile.d/rvm.sh \
- && cd ${REPOS_DIR}/vims-test \
+ && cd ${REPOS_VNFS_DIR}/vims-test \
&& rvm use 1.9.3"
RUN /bin/bash -c ". /etc/profile.d/rvm.sh \
- && cd ${REPOS_DIR}/vims-test \
+ && cd ${REPOS_VNFS_DIR}/vims-test \
&& bundle install"
RUN sh -c 'curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -' \
diff --git a/functest/ci/check_os.sh b/functest/ci/check_os.sh
index 053796d98..e2471026c 100755
--- a/functest/ci/check_os.sh
+++ b/functest/ci/check_os.sh
@@ -24,7 +24,7 @@ fi
echo "Checking OpenStack endpoints:"
-publicURL=$OS_AUTH_URL
+publicURL=$(openstack catalog show identity |awk '/public/ {print $4}')
publicIP=$(echo $publicURL|sed 's/^.*http\:\/\///'|sed 's/.[^:]*$//')
publicPort=$(echo $publicURL|sed 's/^.*://'|sed 's/\/.*$//')
echo ">>Verifying connectivity to the public endpoint $publicIP:$publicPort..."
diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml
index 11ff7fdb5..25be17240 100755
--- a/functest/ci/config_functest.yaml
+++ b/functest/ci/config_functest.yaml
@@ -1,39 +1,39 @@
general:
- directories:
+ dir:
# Relative to the path where the repo is cloned:
- dir_vping: functest/opnfv_tests/openstack/vping
+ vping: functest/opnfv_tests/openstack/vping
dir_odl: functest/opnfv_tests/sdn/odl
- dir_rally: functest/opnfv_tests/openstack/rally
- dir_tempest_cases: functest/opnfv_tests/openstack/tempest/custom_tests
+ rally: functest/opnfv_tests/openstack/rally
+ tempest_cases: functest/opnfv_tests/openstack/tempest/custom_tests
dir_vIMS: functest/opnfv_tests/vnf/ims
dir_onos: functest/opnfv_tests/sdn/onos/teston
dir_onos_sfc: functest/opnfv_tests/sdn/onos/sfc
# Absolute path
- dir_home: /home/opnfv
- dir_repos: /home/opnfv/repos
- dir_repo_functest: /home/opnfv/repos/functest
+ home: /home/opnfv
+ repos: /home/opnfv/repos
+ repo_functest: /home/opnfv/repos/functest
dir_repo_rally: /home/opnfv/repos/rally
- dir_repo_tempest: /home/opnfv/repos/tempest
+ repo_tempest: /home/opnfv/repos/tempest
dir_repo_releng: /home/opnfv/repos/releng
- dir_repo_vims_test: /home/opnfv/repos/vims-test
- dir_repo_sdnvpn: /home/opnfv/repos/sdnvpn
- dir_repo_sfc: /home/opnfv/repos/sfc
+ repo_vims_test: /home/opnfv/repos/vnfs/vims-test
+ repo_sdnvpn: /home/opnfv/repos/sdnvpn
+ repo_sfc: /home/opnfv/repos/sfc
dir_repo_onos: /home/opnfv/repos/onos
dir_repo_promise: /home/opnfv/repos/promise
dir_repo_doctor: /home/opnfv/repos/doctor
- dir_repo_copper: /home/opnfv/repos/copper
+ repo_copper: /home/opnfv/repos/copper
dir_repo_ovno: /home/opnfv/repos/ovno
- dir_repo_parser: /home/opnfv/repos/parser
- dir_repo_domino: /home/opnfv/repos/domino
- dir_repo_snaps: /home/opnfv/repos/snaps
- dir_functest: /home/opnfv/functest
- dir_functest_test: /home/opnfv/repos/functest/functest/opnfv_tests
- dir_results: /home/opnfv/functest/results
- dir_functest_conf: /home/opnfv/functest/conf
- dir_functest_data: /home/opnfv/functest/data
+ repo_parser: /home/opnfv/repos/parser
+ repo_domino: /home/opnfv/repos/domino
+ repo_snaps: /home/opnfv/repos/snaps
+ functest: /home/opnfv/functest
+ functest_test: /home/opnfv/repos/functest/functest/opnfv_tests
+ results: /home/opnfv/functest/results
+ functest_conf: /home/opnfv/functest/conf
+ functest_data: /home/opnfv/functest/data
dir_vIMS_data: /home/opnfv/functest/data/vIMS/
- dir_rally_inst: /home/opnfv/.rally
+ rally_inst: /home/opnfv/.rally
openstack:
creds: /home/opnfv/functest/conf/openstack.creds
@@ -75,12 +75,12 @@ vping:
vm_name_1: opnfv-vping-1
vm_name_2: opnfv-vping-2
image_name: functest-vping
- vping_private_net_name: vping-net
- vping_private_subnet_name: vping-subnet
- vping_private_subnet_cidr: 192.168.130.0/24
- vping_router_name: vping-router
- vping_sg_name: vPing-sg
- vping_sg_descr: Security group for vPing test case
+ private_net_name: vping-net
+ private_subnet_name: vping-subnet
+ private_subnet_cidr: 192.168.130.0/24
+ router_name: vping-router
+ sg_name: vPing-sg
+ sg_desc: Security group for vPing test case
onos_sfc:
image_base_url: http://artifacts.opnfv.org/sfc/demo
@@ -88,6 +88,7 @@ onos_sfc:
image_file_name: firewall_block_image.img
tempest:
+ deployment_name: opnfv-tempest
identity:
tenant_name: tempest
tenant_description: Tenant for Tempest test suite
@@ -109,53 +110,64 @@ rally:
subnet_cidr: 192.168.140.0/24
router_name: rally-router
-vIMS:
- general:
- tenant_name: vIMS
- tenant_description: vIMS Functionality Testing
- images:
- ubuntu:
- image_url: http://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img
- image_name: ubuntu_14.04
- centos:
- image_url: http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1510.qcow2
- image_name: centos_7
- cloudify:
- blueprint:
- url: https://github.com/boucherv-orange/cloudify-manager-blueprints.git
- branch: "3.3.1-build"
- requierments:
- ram_min: 3000
- os_image: centos_7
- inputs:
- keystone_username: ""
- keystone_password: ""
- keystone_tenant_name: ""
- keystone_url: ""
- manager_public_key_name: 'manager-kp'
- agent_public_key_name: 'agent-kp'
- image_id: ""
- flavor_id: "3"
- external_network_name: ""
- ssh_user: centos
- agents_user: ubuntu
- clearwater:
- blueprint:
- file_name: 'openstack-blueprint.yaml'
- name: "clearwater-opnfv"
- destination_folder: "opnfv-cloudify-clearwater"
- url: https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater.git
- branch: "stable"
- deployment-name: 'clearwater-opnfv'
- requierments:
- ram_min: 1700
- os_image: ubuntu_14.04
- inputs:
- image_id: ''
- flavor_id: ''
- agent_user: 'ubuntu'
- external_network_name: ''
- public_domain: clearwater.opnfv
+vnf:
+ aaa:
+ tenant_name: aaa
+ tenant_description: Freeradius server
+ tenant_images: {}
+ juju_epc:
+ tenant_name: epc
+ tenant_description: OAI EPC deployed with Juju
+ tenant_images: {}
+ cloudify_ims:
+ tenant_name: cloudify_ims
+ tenant_description: vIMS
+ tenant_images:
+ ubuntu_14.04: http://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img
+ centos_7: http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1510.qcow2
+ cloudify:
+ blueprint:
+ url: https://github.com/boucherv-orange/cloudify-manager-blueprints.git
+ branch: "3.3.1-build"
+ requierments:
+ ram_min: 3000
+ os_image: centos_7
+ inputs:
+ keystone_username: ""
+ keystone_password: ""
+ keystone_tenant_name: ""
+ keystone_url: ""
+ manager_public_key_name: 'manager-kp'
+ agent_public_key_name: 'agent-kp'
+ image_id: ""
+ flavor_id: "3"
+ external_network_name: ""
+ ssh_user: centos
+ agents_user: ubuntu
+ clearwater:
+ blueprint:
+ file_name: 'openstack-blueprint.yaml'
+ name: "clearwater-opnfv"
+ destination_folder: "opnfv-cloudify-clearwater"
+ url: https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater.git
+ branch: "stable"
+ deployment_name: 'clearwater-opnfv'
+ requirements:
+ ram_min: 1700
+ os_image: ubuntu_14.04
+ inputs:
+ image_id: ''
+ flavor_id: ''
+ agent_user: 'ubuntu'
+ external_network_name: ''
+ public_domain: clearwater.opnfv
+ orchestra_ims:
+ tenant_name: orchestra_ims
+ tenant_description: ims deployed with openbaton
+ opera_ims:
+ tenant_name: opera_ims
+ tenant_description: ims deployed with open-o
+
ONOS:
general:
onosbench_username: 'root'
@@ -174,10 +186,10 @@ ONOS:
installer_master_username: 'root'
installer_master_password: 'r00tme'
multisite:
- fuel_environment:
+ fuel:
installer_username: 'root'
installer_password: 'r00tme'
- compass_environment:
+ compass:
installer_username: 'root'
installer_password: 'root'
multisite_controller_ip: '10.1.0.50'
@@ -197,15 +209,15 @@ promise:
router_name: promise-router
example:
- example_vm_name: example-vm
- example_flavor: m1.small
- example_image_name: functest-example-vm
- example_private_net_name: example-net
- example_private_subnet_name: example-subnet
- example_private_subnet_cidr: 192.168.170.0/24
- example_router_name: example-router
- example_sg_name: example-sg
- example_sg_descr: Example Security group
+ vm_name: example-vm
+ flavor: m1.small
+ image_name: functest-example-vm
+ private_net_name: example-net
+ private_subnet_name: example-subnet
+ private_subnet_cidr: 192.168.170.0/24
+ router_name: example-router
+ sg_name: example-sg
+ sg_desc: Example Security group
results:
test_db_url: http://testresults.opnfv.org/test/api/v1
diff --git a/functest/ci/exec_test.sh b/functest/ci/exec_test.sh
index 2b4cd8b45..7c96d69c3 100755
--- a/functest/ci/exec_test.sh
+++ b/functest/ci/exec_test.sh
@@ -47,11 +47,13 @@ function odl_tests(){
neutron_ip=$(openstack catalog show network | grep publicURL | cut -f3 -d"/" | cut -f1 -d":")
odl_ip=${neutron_ip}
odl_port=8080
+ odl_restport=8181
if [ "$INSTALLER_TYPE" == "fuel" ]; then
odl_port=8282
elif [ "$INSTALLER_TYPE" == "apex" ]; then
odl_ip=$SDN_CONTROLLER_IP
- odl_port=8181
+ odl_port=8081
+ odl_restport=8081
elif [ "$INSTALLER_TYPE" == "joid" ]; then
odl_ip=$SDN_CONTROLLER
elif [ "$INSTALLER_TYPE" == "compass" ]; then
@@ -78,10 +80,15 @@ function run_test(){
odl_tests
[[ "$report" == "-r" ]] && args=-p
${FUNCTEST_TEST_DIR}/sdn/odl/odl.py \
- --keystoneip $keystone_ip --neutronip $neutron_ip \
- --osusername ${OS_USERNAME} --ostenantname ${OS_TENANT_NAME} \
+ --keystoneip $keystone_ip \
+ --neutronip $neutron_ip \
+ --odlip $odl_ip \
+ --odlrestconfport $odl_restport \
+ --odlwebport $odl_port \
--ospassword ${OS_PASSWORD} \
- --odlip $odl_ip --odlwebport $odl_port ${args}
+ --ostenantname ${OS_TENANT_NAME} \
+ --osusername ${OS_USERNAME} \
+ ${args}
;;
"vims")
python ${FUNCTEST_TEST_DIR}/vnf/ims/vims.py $clean_flag $report
@@ -114,7 +121,7 @@ function run_test(){
"security_scan")
echo "Sourcing Credentials ${FUNCTEST_CONF_DIR}/stackrc for undercloud .."
source ${FUNCTEST_CONF_DIR}/stackrc
- python ${REPOS_DIR}/securityscanning/security_scan.py --config ${REPOS_DIR}/securityscanning/config.ini
+ python ${FUNCTEST_TEST_DIR}/security_scan/security_scan.py --config ${FUNCTEST_TEST_DIR}/security_scan/config.ini
;;
"copper")
python ${FUNCTEST_TEST_DIR}/features/copper.py $report
diff --git a/functest/ci/generate_report.py b/functest/ci/generate_report.py
index a90bc5553..89d8fc628 100755
--- a/functest/ci/generate_report.py
+++ b/functest/ci/generate_report.py
@@ -1,11 +1,17 @@
+#!/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
+#
import json
import re
import urllib2
import functest.utils.functest_logger as ft_logger
import functest.utils.functest_utils as ft_utils
-import functest.utils.functest_constants as ft_constants
-
+from functest.utils.constants import CONST
COL_1_LEN = 25
COL_2_LEN = 15
@@ -17,14 +23,6 @@ COL_5_LEN = 75
# and then we can print the url to the specific test result
-class GlobalVariables:
- IS_CI_RUN = ft_constants.IS_CI_RUN
- BUILD_TAG = ft_constants.CI_BUILD_TAG
- INSTALLER = ft_constants.CI_INSTALLER_TYPE
- CI_LOOP = ft_constants.CI_LOOP
- SCENARIO = ft_constants.CI_SCENARIO
-
-
logger = ft_logger.Logger("generate_report").getLogger()
@@ -42,7 +40,7 @@ def init(tiers_to_run):
def get_results_from_db():
url = "%s/results?build_tag=%s" % (ft_utils.get_db_url(),
- GlobalVariables.BUILD_TAG)
+ CONST.BUILD_TAG)
logger.debug("Query to rest api: %s" % url)
try:
data = json.load(urllib2.urlopen(url))
@@ -69,7 +67,7 @@ def print_line(w1, w2='', w3='', w4='', w5=''):
'| ' + w2.ljust(COL_2_LEN - 1) +
'| ' + w3.ljust(COL_3_LEN - 1) +
'| ' + w4.ljust(COL_4_LEN - 1))
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
str += ('| ' + w5.ljust(COL_5_LEN - 1))
str += '|\n'
return str
@@ -77,7 +75,7 @@ def print_line(w1, w2='', w3='', w4='', w5=''):
def print_line_no_columns(str):
TOTAL_LEN = COL_1_LEN + COL_2_LEN + COL_3_LEN + COL_4_LEN + 2
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
TOTAL_LEN += COL_5_LEN + 1
return ('| ' + str.ljust(TOTAL_LEN) + "|\n")
@@ -87,7 +85,7 @@ def print_separator(char="=", delimiter="+"):
delimiter + char * COL_2_LEN +
delimiter + char * COL_3_LEN +
delimiter + char * COL_4_LEN)
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
str += (delimiter + char * COL_5_LEN)
str += '+\n'
return str
@@ -96,7 +94,7 @@ def print_separator(char="=", delimiter="+"):
def main(args):
executed_test_cases = args
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
results = get_results_from_db()
if results is not None:
for test in executed_test_cases:
@@ -105,15 +103,15 @@ def main(args):
"result": data['result']})
TOTAL_LEN = COL_1_LEN + COL_2_LEN + COL_3_LEN + COL_4_LEN
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
TOTAL_LEN += COL_5_LEN
MID = TOTAL_LEN / 2
- if GlobalVariables.BUILD_TAG is not None:
- if re.search("daily", GlobalVariables.BUILD_TAG) is not None:
- GlobalVariables.CI_LOOP = "daily"
+ if CONST.BUILD_TAG is not None:
+ if re.search("daily", CONST.BUILD_TAG) is not None:
+ CONST.CI_LOOP = "daily"
else:
- GlobalVariables.CI_LOOP = "weekly"
+ CONST.CI_LOOP = "weekly"
str = ''
str += print_separator('=', delimiter="=")
@@ -122,19 +120,19 @@ def main(args):
str += print_line_no_columns(' ')
str += print_line_no_columns(" Deployment description:")
str += print_line_no_columns(" INSTALLER: %s"
- % GlobalVariables.INSTALLER)
- if GlobalVariables.SCENARIO is not None:
+ % CONST.INSTALLER_TYPE)
+ if CONST.DEPLOY_SCENARIO is not None:
str += print_line_no_columns(" SCENARIO: %s"
- % GlobalVariables.SCENARIO)
- if GlobalVariables.BUILD_TAG is not None:
+ % CONST.DEPLOY_SCENARIO)
+ if CONST.BUILD_TAG is not None:
str += print_line_no_columns(" BUILD TAG: %s"
- % GlobalVariables.BUILD_TAG)
- if GlobalVariables.CI_LOOP is not None:
+ % CONST.BUILD_TAG)
+ if CONST.CI_LOOP is not None:
str += print_line_no_columns(" CI LOOP: %s"
- % GlobalVariables.CI_LOOP)
+ % CONST.CI_LOOP)
str += print_line_no_columns(' ')
str += print_separator('=')
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
str += print_line('TEST CASE', 'TIER', 'DURATION', 'RESULT', 'URL')
else:
str += print_line('TEST CASE', 'TIER', 'DURATION', 'RESULT')
diff --git a/functest/ci/prepare_env.py b/functest/ci/prepare_env.py
index 41cbbe098..74c751af9 100755
--- a/functest/ci/prepare_env.py
+++ b/functest/ci/prepare_env.py
@@ -13,35 +13,28 @@
#
+import argparse
import json
import os
import re
import subprocess
import sys
-import argparse
import yaml
+from opnfv.utils import constants as opnfv_constants
import functest.utils.functest_logger as ft_logger
import functest.utils.functest_utils as ft_utils
import functest.utils.openstack_utils as os_utils
-import functest.utils.functest_constants as ft_constants
-
-from opnfv.utils import constants as opnfv_constants
+from functest.utils.constants import CONST
actions = ['start', 'check']
-parser = argparse.ArgumentParser()
-parser.add_argument("action", help="Possible actions are: "
- "'{d[0]}|{d[1]}' ".format(d=actions))
-parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
-args = parser.parse_args()
-
""" logging configuration """
logger = ft_logger.Logger("prepare_env").getLogger()
-CONFIG_FUNCTEST_PATH = ft_constants.CONFIG_FUNCTEST_YAML
+CONFIG_FUNCTEST_PATH = CONST.CONFIG_FUNCTEST_YAML
CONFIG_PATCH_PATH = os.path.join(os.path.dirname(
CONFIG_FUNCTEST_PATH), "config_patch.yaml")
@@ -49,6 +42,19 @@ with open(CONFIG_PATCH_PATH) as f:
functest_patch_yaml = yaml.safe_load(f)
+class PrepareEnvParser():
+
+ def __init__(self):
+ self.parser = argparse.ArgumentParser()
+ self.parser.add_argument("action", help="Possible actions are: "
+ "'{d[0]}|{d[1]}' ".format(d=actions))
+ self.parser.add_argument("-d", "--debug", help="Debug mode",
+ action="store_true")
+
+ def parse_args(self, argv=[]):
+ return vars(self.parser.parse_args(argv))
+
+
def print_separator():
logger.info("==============================================")
@@ -57,97 +63,97 @@ def check_env_variables():
print_separator()
logger.info("Checking environment variables...")
- if ft_constants.CI_INSTALLER_TYPE is None:
+ if CONST.INSTALLER_TYPE is None:
logger.warning("The env variable 'INSTALLER_TYPE' is not defined.")
- ft_constants.CI_INSTALLER_TYPE = "undefined"
+ CONST.INSTALLER_TYPE = "undefined"
else:
- if ft_constants.CI_INSTALLER_TYPE not in ft_constants.INSTALLERS:
+ if CONST.INSTALLER_TYPE not in opnfv_constants.INSTALLERS:
logger.warning("INSTALLER_TYPE=%s is not a valid OPNFV installer. "
"Available OPNFV Installers are : %s. "
"Setting INSTALLER_TYPE=undefined."
- % (ft_constants.CI_INSTALLER_TYPE,
- ft_constants.INSTALLERS))
- ft_constants.CI_INSTALLER_TYPE = "undefined"
+ % (CONST.INSTALLER_TYPE,
+ opnfv_constants.INSTALLERS))
+ CONST.INSTALLER_TYPE = "undefined"
else:
logger.info(" INSTALLER_TYPE=%s"
- % ft_constants.CI_INSTALLER_TYPE)
+ % CONST.INSTALLER_TYPE)
- if ft_constants.CI_INSTALLER_IP is None:
+ if CONST.INSTALLER_IP is None:
logger.warning("The env variable 'INSTALLER_IP' is not defined. "
"It is needed to fetch the OpenStack credentials. "
"If the credentials are not provided to the "
"container as a volume, please add this env variable "
"to the 'docker run' command.")
else:
- logger.info(" INSTALLER_IP=%s" % ft_constants.CI_INSTALLER_IP)
+ logger.info(" INSTALLER_IP=%s" % CONST.INSTALLER_IP)
- if ft_constants.CI_SCENARIO is None:
+ if CONST.DEPLOY_SCENARIO is None:
logger.warning("The env variable 'DEPLOY_SCENARIO' is not defined. "
"Setting CI_SCENARIO=undefined.")
- ft_constants.CI_SCENARIO = "undefined"
+ CONST.DEPLOY_SCENARIO = "undefined"
else:
- logger.info(" DEPLOY_SCENARIO=%s" % ft_constants.CI_SCENARIO)
- if ft_constants.CI_DEBUG:
- logger.info(" CI_DEBUG=%s" % ft_constants.CI_DEBUG)
+ logger.info(" DEPLOY_SCENARIO=%s" % CONST.DEPLOY_SCENARIO)
+ if CONST.CI_DEBUG:
+ logger.info(" CI_DEBUG=%s" % CONST.CI_DEBUG)
- if ft_constants.CI_NODE:
- logger.info(" NODE_NAME=%s" % ft_constants.CI_NODE)
+ if CONST.NODE_NAME:
+ logger.info(" NODE_NAME=%s" % CONST.NODE_NAME)
- if ft_constants.CI_BUILD_TAG:
- logger.info(" BUILD_TAG=%s" % ft_constants.CI_BUILD_TAG)
+ if CONST.BUILD_TAG:
+ logger.info(" BUILD_TAG=%s" % CONST.BUILD_TAG)
- if ft_constants.IS_CI_RUN:
- logger.info(" IS_CI_RUN=%s" % ft_constants.IS_CI_RUN)
+ if CONST.IS_CI_RUN:
+ logger.info(" IS_CI_RUN=%s" % CONST.IS_CI_RUN)
def create_directories():
print_separator()
logger.info("Creating needed directories...")
- if not os.path.exists(ft_constants.FUNCTEST_CONF_DIR):
- os.makedirs(ft_constants.FUNCTEST_CONF_DIR)
- logger.info(" %s created." % ft_constants.FUNCTEST_CONF_DIR)
+ if not os.path.exists(CONST.dir_functest_conf):
+ os.makedirs(CONST.dir_functest_conf)
+ logger.info(" %s created." % CONST.dir_functest_conf)
else:
logger.debug(" %s already exists."
- % ft_constants.FUNCTEST_CONF_DIR)
+ % CONST.dir_functest_conf)
- if not os.path.exists(ft_constants.FUNCTEST_DATA_DIR):
- os.makedirs(ft_constants.FUNCTEST_DATA_DIR)
- logger.info(" %s created." % ft_constants.FUNCTEST_DATA_DIR)
+ if not os.path.exists(CONST.dir_functest_data):
+ os.makedirs(CONST.dir_functest_data)
+ logger.info(" %s created." % CONST.dir_functest_data)
else:
logger.debug(" %s already exists."
- % ft_constants.FUNCTEST_DATA_DIR)
+ % CONST.dir_functest_data)
def source_rc_file():
print_separator()
logger.info("Fetching RC file...")
- if ft_constants.OPENSTACK_CREDS is None:
+ if CONST.openstack_creds is None:
logger.warning("The environment variable 'creds' must be set and"
"pointing to the local RC file. Using default: "
"/home/opnfv/functest/conf/openstack.creds ...")
- os.path.join(ft_constants.FUNCTEST_CONF_DIR, 'openstack.creds')
+ os.path.join(CONST.dir_functest_conf, 'openstack.creds')
- if not os.path.isfile(ft_constants.OPENSTACK_CREDS):
+ if not os.path.isfile(CONST.openstack_creds):
logger.info("RC file not provided. "
"Fetching it from the installer...")
- if ft_constants.CI_INSTALLER_IP is None:
+ if CONST.INSTALLER_IP is None:
logger.error("The env variable CI_INSTALLER_IP must be provided in"
" order to fetch the credentials from the installer.")
sys.exit("Missing CI_INSTALLER_IP.")
- if ft_constants.CI_INSTALLER_TYPE not in ft_constants.INSTALLERS:
+ if CONST.INSTALLER_TYPE not in opnfv_constants.INSTALLERS:
logger.error("Cannot fetch credentials. INSTALLER_TYPE=%s is "
"not a valid OPNFV installer. Available "
"installers are : %s." %
- (ft_constants.CI_INSTALLER_TYPE,
+ (CONST.INSTALLER_TYPE,
opnfv_constants.INSTALLERS))
sys.exit("Wrong INSTALLER_TYPE.")
cmd = ("/home/opnfv/repos/releng/utils/fetch_os_creds.sh "
"-d %s -i %s -a %s"
- % (ft_constants.OPENSTACK_CREDS,
- ft_constants.CI_INSTALLER_TYPE,
- ft_constants.CI_INSTALLER_IP))
+ % (CONST.openstack_creds,
+ CONST.INSTALLER_TYPE,
+ CONST.INSTALLER_IP))
logger.debug("Executing command: %s" % cmd)
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
output = p.communicate()[0]
@@ -157,38 +163,38 @@ def source_rc_file():
sys.exit(1)
else:
logger.info("RC file provided in %s."
- % ft_constants.OPENSTACK_CREDS)
- if os.path.getsize(ft_constants.OPENSTACK_CREDS) == 0:
+ % CONST.openstack_creds)
+ if os.path.getsize(CONST.openstack_creds) == 0:
logger.error("The file %s is empty."
- % ft_constants.OPENSTACK_CREDS)
+ % CONST.openstack_creds)
sys.exit(1)
logger.info("Sourcing the OpenStack RC file...")
creds = os_utils.source_credentials(
- ft_constants.OPENSTACK_CREDS)
+ CONST.openstack_creds)
str = ""
for key, value in creds.iteritems():
if re.search("OS_", key):
str += "\n\t\t\t\t\t\t " + key + "=" + value
if key == 'OS_AUTH_URL':
- ft_constants.OS_AUTH_URL = value
+ CONST.OS_AUTH_URL = value
elif key == 'OS_USERNAME':
- ft_constants.OS_USERNAME = value
+ CONST.OS_USERNAME = value
elif key == 'OS_TENANT_NAME':
- ft_constants.OS_TENANT_NAME = value
+ CONST.OS_TENANT_NAME = value
elif key == 'OS_PASSWORD':
- ft_constants.OS_PASSWORD = value
+ CONST.OS_PASSWORD = value
logger.debug("Used credentials: %s" % str)
- logger.debug("OS_AUTH_URL:%s" % ft_constants.OS_AUTH_URL)
- logger.debug("OS_USERNAME:%s" % ft_constants.OS_USERNAME)
- logger.debug("OS_TENANT_NAME:%s" % ft_constants.OS_TENANT_NAME)
- logger.debug("OS_PASSWORD:%s" % ft_constants.OS_PASSWORD)
+ logger.debug("OS_AUTH_URL:%s" % CONST.OS_AUTH_URL)
+ logger.debug("OS_USERNAME:%s" % CONST.OS_USERNAME)
+ logger.debug("OS_TENANT_NAME:%s" % CONST.OS_TENANT_NAME)
+ logger.debug("OS_PASSWORD:%s" % CONST.OS_PASSWORD)
def patch_config_file():
updated = False
for key in functest_patch_yaml:
- if key in ft_constants.CI_SCENARIO:
+ if key in CONST.DEPLOY_SCENARIO:
new_functest_yaml = dict(ft_utils.merge_dicts(
ft_utils.get_functest_yaml(), functest_patch_yaml[key]))
updated = True
@@ -203,7 +209,7 @@ def patch_config_file():
def verify_deployment():
print_separator()
logger.info("Verifying OpenStack services...")
- cmd = ("%s/functest/ci/check_os.sh" % ft_constants.FUNCTEST_REPO_DIR)
+ cmd = ("%s/functest/ci/check_os.sh" % CONST.dir_repo_functest)
logger.debug("Executing command: %s" % cmd)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
@@ -223,60 +229,64 @@ def install_rally():
cmd = "rally deployment destroy opnfv-rally"
ft_utils.execute_command(cmd, error_msg=(
"Deployment %s does not exist."
- % ft_constants.RALLY_DEPLOYMENT_NAME),
+ % CONST.rally_deployment_name),
verbose=False)
rally_conf = os_utils.get_credentials_for_rally()
with open('rally_conf.json', 'w') as fp:
json.dump(rally_conf, fp)
- cmd = "rally deployment create --file=rally_conf.json --name="
- cmd += ft_constants.RALLY_DEPLOYMENT_NAME
- ft_utils.execute_command(cmd,
- error_msg="Problem creating Rally deployment")
-
- logger.info("Installing tempest from existing repo...")
- cmd = ("rally verify install --source " +
- ft_constants.TEMPEST_REPO_DIR +
- " --system-wide")
+ cmd = ("rally deployment create "
+ "--file=rally_conf.json --name={}"
+ .format(CONST.rally_deployment_name))
ft_utils.execute_command(cmd,
- error_msg="Problem installing Tempest.")
+ error_msg=("Problem while creating "
+ "Rally deployment"))
cmd = "rally deployment check"
ft_utils.execute_command(cmd,
error_msg=("OpenStack not responding or "
"faulty Rally deployment."))
- cmd = "rally show images"
+ cmd = "rally deployment list"
ft_utils.execute_command(cmd,
error_msg=("Problem while listing "
- "OpenStack images."))
+ "Rally deployment."))
- cmd = "rally show flavors"
+ cmd = "rally plugin list | head -5"
ft_utils.execute_command(cmd,
error_msg=("Problem while showing "
- "OpenStack flavors."))
+ "Rally plugins."))
+
+
+def install_tempest():
+ logger.info("Installing tempest from existing repo...")
+ cmd = ("rally verify create-verifier --source {0} "
+ "--name {1} --type tempest"
+ .format(CONST.dir_repo_tempest, CONST.tempest_deployment_name))
+ ft_utils.execute_command(cmd,
+ error_msg="Problem while installing Tempest.")
def check_environment():
msg_not_active = "The Functest environment is not installed."
- if not os.path.isfile(ft_constants.ENV_FILE):
+ if not os.path.isfile(CONST.env_active):
logger.error(msg_not_active)
sys.exit(1)
- with open(ft_constants.ENV_FILE, "r") as env_file:
+ with open(CONST.env_active, "r") as env_file:
s = env_file.read()
if not re.search("1", s):
logger.error(msg_not_active)
sys.exit(1)
- logger.info("Functest environment installed.")
+ logger.info("Functest environment is installed.")
-def main():
- if not (args.action in actions):
+def main(**kwargs):
+ if not (kwargs['action'] in actions):
logger.error('Argument not valid.')
sys.exit()
- if args.action == "start":
+ if kwargs['action'] == "start":
logger.info("######### Preparing Functest environment #########\n")
check_env_variables()
create_directories()
@@ -284,17 +294,20 @@ def main():
patch_config_file()
verify_deployment()
install_rally()
+ install_tempest()
- with open(ft_constants.ENV_FILE, "w") as env_file:
+ with open(CONST.env_active, "w") as env_file:
env_file.write("1")
check_environment()
- if args.action == "check":
+ if kwargs['action'] == "check":
check_environment()
exit(0)
if __name__ == '__main__':
- main()
+ parser = PrepareEnvParser()
+ args = parser.parse_args(sys.argv[1:])
+ main(**args)
diff --git a/functest/ci/run_tests.py b/functest/ci/run_tests.py
index 557ba08dd..a5f1ab9e8 100755
--- a/functest/ci/run_tests.py
+++ b/functest/ci/run_tests.py
@@ -8,35 +8,23 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
+import argparse
import datetime
import importlib
import os
import re
import sys
-import argparse
-
import functest.ci.generate_report as generate_report
import functest.ci.tier_builder as tb
import functest.core.testcase_base as testcase_base
+import functest.utils.functest_constants as ft_constants
import functest.utils.functest_logger as ft_logger
import functest.utils.functest_utils as ft_utils
-import functest.utils.functest_constants as ft_constants
import functest.utils.openstack_clean as os_clean
import functest.utils.openstack_snapshot as os_snapshot
import functest.utils.openstack_utils as os_utils
-
-
-parser = argparse.ArgumentParser()
-parser.add_argument("-t", "--test", dest="test", action='store',
- help="Test case or tier (group of tests) to be executed. "
- "It will run all the test if not specified.")
-parser.add_argument("-n", "--noclean", help="Do not clean OpenStack resources"
- " after running each test (default=false).",
- action="store_true")
-parser.add_argument("-r", "--report", help="Push results to database "
- "(default=false).", action="store_true")
-args = parser.parse_args()
+from functest.utils.constants import CONST
""" logging configuration """
@@ -44,12 +32,32 @@ logger = ft_logger.Logger("run_tests").getLogger()
""" global variables """
-EXEC_SCRIPT = ("%s/functest/ci/exec_test.sh" % ft_constants.FUNCTEST_REPO_DIR)
+EXEC_SCRIPT = ("%s/functest/ci/exec_test.sh" % CONST.dir_repo_functest)
# This will be the return code of this script. If any of the tests fails,
# this variable will change to -1
+class RunTestsParser():
+
+ def __init__(self):
+ self.parser = argparse.ArgumentParser()
+ self.parser.add_argument("-t", "--test", dest="test", action='store',
+ help="Test case or tier (group of tests) "
+ "to be executed. It will run all the test "
+ "if not specified.")
+ self.parser.add_argument("-n", "--noclean", help="Do not clean "
+ "OpenStack resources after running each "
+ "test (default=false).",
+ action="store_true")
+ self.parser.add_argument("-r", "--report", help="Push results to "
+ "database (default=false).",
+ action="store_true")
+
+ def parse_args(self, argv=[]):
+ return vars(self.parser.parse_args(argv))
+
+
class GlobalVariables:
EXECUTED_TEST_CASES = []
OVERALL_RESULT = 0
@@ -65,7 +73,7 @@ def print_separator(str, count=45):
def source_rc_file():
- rc_file = ft_constants.OPENSTACK_CREDS
+ rc_file = CONST.openstack_creds
if not os.path.isfile(rc_file):
logger.error("RC file %s does not exist..." % rc_file)
sys.exit(1)
@@ -75,16 +83,20 @@ def source_rc_file():
if re.search("OS_", key):
if key == 'OS_AUTH_URL':
ft_constants.OS_AUTH_URL = value
+ CONST.OS_AUTH_URL = value
elif key == 'OS_USERNAME':
ft_constants.OS_USERNAME = value
+ CONST.OS_USERNAME = value
elif key == 'OS_TENANT_NAME':
ft_constants.OS_TENANT_NAME = value
+ CONST.OS_TENANT_NAME = value
elif key == 'OS_PASSWORD':
ft_constants.OS_PASSWORD = value
- logger.debug("OS_AUTH_URL:%s" % ft_constants.OS_AUTH_URL)
- logger.debug("OS_USERNAME:%s" % ft_constants.OS_USERNAME)
- logger.debug("OS_TENANT_NAME:%s" % ft_constants.OS_TENANT_NAME)
- logger.debug("OS_PASSWORD:%s" % ft_constants.OS_PASSWORD)
+ CONST.OS_PASSWORD = value
+ logger.debug("OS_AUTH_URL:%s" % CONST.OS_AUTH_URL)
+ logger.debug("OS_USERNAME:%s" % CONST.OS_USERNAME)
+ logger.debug("OS_TENANT_NAME:%s" % CONST.OS_TENANT_NAME)
+ logger.debug("OS_PASSWORD:%s" % CONST.OS_PASSWORD)
def generate_os_snapshot():
@@ -115,7 +127,7 @@ def get_run_dict_if_defined(testname):
return None
-def run_test(test, tier_name):
+def run_test(test, tier_name, testcases=None):
result_str = "PASS"
start = datetime.datetime.now()
test_name = test.get_name()
@@ -143,7 +155,7 @@ def run_test(test, tier_name):
result = test_case.run()
if result == testcase_base.TestcaseBase.EX_OK:
if GlobalVariables.REPORT_FLAG:
- test_case.push_to_db()
+ test_case.publish_report()
result = test_case.check_criteria()
except ImportError:
logger.exception("Cannot import module {}".format(
@@ -167,18 +179,19 @@ def run_test(test, tier_name):
if result != 0:
logger.error("The test case '%s' failed. " % test_name)
- OVERALL_RESULT = -1
+ GlobalVariables.OVERALL_RESULT = -1
result_str = "FAIL"
if test.is_blocking():
- if not args.test or args.test == "all":
+ if not testcases or testcases == "all":
logger.info("This test case is blocking. Aborting overall "
"execution.")
# if it is a single test we don't print the whole results table
update_test_info(test_name, result_str, duration_str)
generate_report.main(GlobalVariables.EXECUTED_TEST_CASES)
- logger.info("Execution exit value: %s" % OVERALL_RESULT)
- sys.exit(OVERALL_RESULT)
+ logger.info("Execution exit value: %s" %
+ GlobalVariables.OVERALL_RESULT)
+ sys.exit(GlobalVariables.OVERALL_RESULT)
update_test_info(test_name, result_str, duration_str)
@@ -201,17 +214,11 @@ def run_tier(tier):
def run_all(tiers):
summary = ""
- BUILD_TAG = ft_constants.CI_BUILD_TAG
- if BUILD_TAG is not None and re.search("daily", BUILD_TAG) is not None:
- CI_LOOP = "daily"
- else:
- CI_LOOP = "weekly"
-
tiers_to_run = []
for tier in tiers.get_tiers():
if (len(tier.get_tests()) != 0 and
- re.search(CI_LOOP, tier.get_ci_loop()) is not None):
+ re.search(CONST.CI_LOOP, tier.get_ci_loop()) is not None):
tiers_to_run.append(tier)
summary += ("\n - %s:\n\t %s"
% (tier.get_name(),
@@ -225,35 +232,37 @@ def run_all(tiers):
generate_report.main(GlobalVariables.EXECUTED_TEST_CASES)
-def main():
+def main(**kwargs):
- CI_INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
- CI_SCENARIO = ft_constants.CI_SCENARIO
+ CI_INSTALLER_TYPE = CONST.INSTALLER_TYPE
+ CI_SCENARIO = CONST.DEPLOY_SCENARIO
- file = ft_constants.FUNCTEST_TESTCASES_YAML
+ file = CONST.functest_testcases_yaml
_tiers = tb.TierBuilder(CI_INSTALLER_TYPE, CI_SCENARIO, file)
- if args.noclean:
+ if kwargs['noclean']:
GlobalVariables.CLEAN_FLAG = False
- if args.report:
+ if kwargs['report']:
GlobalVariables.REPORT_FLAG = True
- if args.test:
+ if kwargs['test']:
source_rc_file()
- if _tiers.get_tier(args.test):
- run_tier(_tiers.get_tier(args.test))
+ if _tiers.get_tier(kwargs['test']):
+ run_tier(_tiers.get_tier(kwargs['test']))
- elif _tiers.get_test(args.test):
- run_test(_tiers.get_test(args.test), _tiers.get_tier(args.test))
+ elif _tiers.get_test(kwargs['test']):
+ run_test(_tiers.get_test(kwargs['test']),
+ _tiers.get_tier(kwargs['test']),
+ kwargs['test'])
- elif args.test == "all":
+ elif kwargs['test'] == "all":
run_all(_tiers)
else:
logger.error("Unknown test case or tier '%s', or not supported by "
"the given scenario '%s'."
- % (args.test, CI_SCENARIO))
+ % (kwargs['test'], CI_SCENARIO))
logger.debug("Available tiers are:\n\n%s"
% _tiers)
else:
@@ -264,4 +273,6 @@ def main():
if __name__ == '__main__':
- main()
+ parser = RunTestsParser()
+ args = parser.parse_args(sys.argv[1:])
+ main(**args)
diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml
index 6f57c7030..ede082856 100755
--- a/functest/ci/testcases.yaml
+++ b/functest/ci/testcases.yaml
@@ -65,11 +65,12 @@ tiers:
Tempest automatically and depends on the parameters of
the OpenStack deplopyment.
dependencies:
- installer: ''
+ installer: '^((?!netvirt).)*$'
scenario: ''
run:
module: 'functest.opnfv_tests.openstack.tempest.tempest'
class: 'TempestSmokeSerial'
+
-
name: rally_sanity
criteria: 'success_rate == 100%'
@@ -120,7 +121,7 @@ tiers:
the cloud's private network.
dependencies:
- installer: ''
+ installer: '^((?!netvirt).)*$'
scenario: ''
run:
module: 'functest.opnfv_tests.openstack.snaps.connection_check'
@@ -138,7 +139,7 @@ tiers:
the cloud's private network.
dependencies:
- installer: ''
+ installer: '^((?!netvirt).)*$'
scenario: ''
run:
module: 'functest.opnfv_tests.openstack.snaps.api_check'
@@ -158,7 +159,7 @@ tiers:
the cloud's private network.
dependencies:
- installer: ''
+ installer: '^((?!netvirt).)*$'
scenario: ''
run:
module: 'functest.opnfv_tests.openstack.snaps.smoke'
@@ -199,7 +200,7 @@ tiers:
description: >-
Test suite from SDNVPN project.
dependencies:
- installer: '(fuel)|(apex)'
+ installer: '(fuel)|(apex)|(netvirt)'
scenario: 'bgpvpn'
run:
module: 'functest.opnfv_tests.features.sdnvpn'
@@ -214,7 +215,6 @@ tiers:
dependencies:
installer: 'apex'
scenario: '^((?!fdio).)*$'
-
-
name: copper
criteria: 'status == "PASS"'
@@ -227,7 +227,6 @@ tiers:
run:
module: 'functest.opnfv_tests.features.copper'
class: 'Copper'
-
-
name: moon
criteria: 'status == "PASS"'
@@ -282,6 +281,18 @@ tiers:
run:
module: 'functest.opnfv_tests.vnf.rnc.parser'
class: 'Parser'
+ -
+ name: orchestra
+ criteria: 'ret == 0'
+ blocking: false
+ description: >-
+ Test OpenBaton (Orchestra) stack
+ dependencies:
+ installer: 'joid'
+ scenario: 'unknown'
+ run:
+ module: 'functest.opnfv_tests.features.orchestrator.orchestra'
+ class: 'OpenbatonOrchestrator'
-
name: components
order: 3
@@ -298,7 +309,7 @@ tiers:
Tempest automatically and depends on the parameters of
the OpenStack deplopyment.
dependencies:
- installer: ''
+ installer: '^((?!netvirt).)*$'
scenario: ''
run:
module: 'functest.opnfv_tests.openstack.tempest.tempest'
@@ -312,7 +323,7 @@ tiers:
This test case runs the full suite of scenarios of the OpenStack
Rally suite using several threads and iterations.
dependencies:
- installer: ''
+ installer: '^((?!netvirt).)*$'
scenario: ''
-
@@ -323,7 +334,7 @@ tiers:
Collection of VNF test cases.
testcases:
-
- name: vims
+ name: cloudify_ims
criteria: 'status == "PASS"'
blocking: false
description: >-
@@ -332,3 +343,57 @@ tiers:
dependencies:
installer: ''
scenario: '(ocl)|(nosdn)|^(os-odl)((?!bgpvpn).)*$'
+ run:
+ module: 'functest.opnfv_tests.vnf.ims.cloudify_ims'
+ class: 'ImsVnf'
+ -
+ name: aaa
+ criteria: 'ret == 0'
+ blocking: false
+ description: >-
+ Test suite from Parser project.
+ dependencies:
+ installer: ''
+ scenario: ''
+ run:
+ module: 'functest.opnfv_tests.vnf.aaa.aaa'
+ class: 'AaaVnf'
+
+ -
+ name: juju_epc
+ criteria: 'ret == 0'
+ blocking: false
+ description: >-
+ Test suite from OAI project, vEPC deployed with Juju.
+ dependencies:
+ installer: 'unknown'
+ scenario: 'unknown'
+ run:
+ module: 'functest.opnfv_tests.vnf.epc.epc'
+ class: 'EpcVnf'
+
+ -
+ name: orchestra_ims
+ criteria: 'ret == 0'
+ blocking: false
+ description: >-
+ VNF deployment with OpenBaton (Orchestra)
+ dependencies:
+ installer: 'unknown'
+ scenario: 'unknown'
+ run:
+ module: 'functest.opnfv_tests.vnf.ims.orchestra_ims'
+ class: 'ImsVnf'
+
+ -
+ name: opera_ims
+ criteria: 'ret == 0'
+ blocking: false
+ description: >-
+ Evolution of vIMS
+ dependencies:
+ installer: 'unknown'
+ scenario: 'unknown'
+ run:
+ module: 'functest.opnfv_tests.vnf.ims.opera_ims'
+ class: 'ImsVnf'
diff --git a/functest/cli/cli_base.py b/functest/cli/cli_base.py
index 3b14fa336..cc697ed7e 100644
--- a/functest/cli/cli_base.py
+++ b/functest/cli/cli_base.py
@@ -121,8 +121,11 @@ def testcase_show(testname):
@click.option('-n', '--noclean', is_flag=True, default=False,
help='The created openstack resources by the test'
'will not be cleaned after the execution.')
-def testcase_run(testname, noclean):
- _testcase.run(testname, noclean)
+@click.option('-r', '--report', is_flag=True, default=False,
+ help='Push results to the results DataBase. Only CI Pods'
+ 'have rights to do that.')
+def testcase_run(testname, noclean, report):
+ _testcase.run(testname, noclean, report)
@tier.command('list', help="Lists the available tiers.")
@@ -147,5 +150,8 @@ def tier_gettests(tiername):
@click.option('-n', '--noclean', is_flag=True, default=False,
help='The created openstack resources by the tests'
'will not be cleaned after the execution.')
-def tier_run(tiername, noclean):
- _tier.run(tiername, noclean)
+@click.option('-r', '--report', is_flag=True, default=False,
+ help='Push results to the results DataBase. Only CI Pods'
+ 'have rights to do that.')
+def tier_run(tiername, noclean, report):
+ _tier.run(tiername, noclean, report)
diff --git a/functest/cli/commands/cli_env.py b/functest/cli/commands/cli_env.py
index 9f793e71f..9423631bf 100644
--- a/functest/cli/commands/cli_env.py
+++ b/functest/cli/commands/cli_env.py
@@ -12,8 +12,8 @@ import os
import click
import git
+from functest.utils.constants import CONST
import functest.utils.functest_utils as ft_utils
-import functest.utils.functest_constants as ft_constants
class CliEnv:
@@ -28,7 +28,7 @@ class CliEnv:
"it again? [y|n]\n")
while True:
if answer.lower() in ["y", "yes"]:
- os.remove(ft_constants.ENV_FILE)
+ os.remove(CONST.env_active)
break
elif answer.lower() in ["n", "no"]:
return
@@ -36,40 +36,32 @@ class CliEnv:
answer = raw_input("Invalid answer. Please type [y|n]\n")
cmd = ("python %s/functest/ci/prepare_env.py start" %
- ft_constants.FUNCTEST_REPO_DIR)
+ CONST.dir_repo_functest)
ft_utils.execute_command(cmd)
def show(self):
- CI_INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
- if CI_INSTALLER_TYPE is None:
- CI_INSTALLER_TYPE = "Unknown"
- CI_INSTALLER_IP = ft_constants.CI_INSTALLER_IP
- if CI_INSTALLER_IP is None:
- CI_INSTALLER_IP = "Unknown"
- CI_INSTALLER = ("%s, %s" % (CI_INSTALLER_TYPE, CI_INSTALLER_IP))
-
- CI_SCENARIO = ft_constants.CI_SCENARIO
- if CI_SCENARIO is None:
- CI_SCENARIO = "Unknown"
-
- CI_NODE = ft_constants.CI_NODE
- if CI_NODE is None:
- CI_NODE = "Unknown"
-
- repo = git.Repo(ft_constants.FUNCTEST_REPO_DIR)
- branch = repo.head.reference
- GIT_BRANCH = branch.name
- GIT_HASH = branch.commit.hexsha
-
- CI_BUILD_TAG = ft_constants.CI_BUILD_TAG
- if CI_BUILD_TAG is not None:
- CI_BUILD_TAG = CI_BUILD_TAG.lstrip(
+ def _get_value(attr, default='Unknown'):
+ return attr if attr else default
+
+ install_type = _get_value(CONST.INSTALLER_TYPE)
+ installer_ip = _get_value(CONST.INSTALLER_IP)
+ installer_info = ("%s, %s" % (install_type, installer_ip))
+ scenario = _get_value(CONST.DEPLOY_SCENARIO)
+ node = _get_value(CONST.NODE_NAME)
+ repo_h = git.Repo(CONST.dir_repo_functest).head
+ if repo_h.is_detached:
+ git_branch = 'detached from FETCH_HEAD'
+ git_hash = repo_h.commit.hexsha
+ else:
+ branch = repo_h.reference
+ git_branch = branch.name
+ git_hash = branch.commit.hexsha
+ is_debug = _get_value(CONST.CI_DEBUG, 'false')
+ build_tag = CONST.BUILD_TAG
+ if build_tag is not None:
+ build_tag = build_tag.lstrip(
"jenkins-").lstrip("functest").lstrip("-")
- CI_DEBUG = ft_constants.CI_DEBUG
- if CI_DEBUG is None:
- CI_DEBUG = "false"
-
STATUS = "not ready"
if self.status(verbose=False) == 0:
STATUS = "ready"
@@ -77,14 +69,14 @@ class CliEnv:
click.echo("+======================================================+")
click.echo("| Functest Environment info |")
click.echo("+======================================================+")
- click.echo("| INSTALLER: %s|" % CI_INSTALLER.ljust(41))
- click.echo("| SCENARIO: %s|" % CI_SCENARIO.ljust(41))
- click.echo("| POD: %s|" % CI_NODE.ljust(41))
- click.echo("| GIT BRACNH: %s|" % GIT_BRANCH.ljust(41))
- click.echo("| GIT HASH: %s|" % GIT_HASH.ljust(41))
- if CI_BUILD_TAG:
- click.echo("| BUILD TAG: %s|" % CI_BUILD_TAG.ljust(41))
- click.echo("| DEBUG FLAG: %s|" % CI_DEBUG.ljust(41))
+ click.echo("| INSTALLER: %s|" % installer_info.ljust(41))
+ click.echo("| SCENARIO: %s|" % scenario.ljust(41))
+ click.echo("| POD: %s|" % node.ljust(41))
+ click.echo("| GIT BRACNH: %s|" % git_branch.ljust(41))
+ click.echo("| GIT HASH: %s|" % git_hash.ljust(41))
+ if build_tag:
+ click.echo("| BUILD TAG: %s|" % build_tag.ljust(41))
+ click.echo("| DEBUG FLAG: %s|" % is_debug.ljust(41))
click.echo("+------------------------------------------------------+")
click.echo("| STATUS: %s|" % STATUS.ljust(41))
click.echo("+------------------------------------------------------+")
@@ -92,7 +84,7 @@ class CliEnv:
def status(self, verbose=True):
ret_val = 0
- if not os.path.isfile(ft_constants.ENV_FILE):
+ if not os.path.isfile(CONST.env_active):
if verbose:
click.echo("Functest environment is not installed.\n")
ret_val = 1
diff --git a/functest/cli/commands/cli_os.py b/functest/cli/commands/cli_os.py
index bb8592195..aeb34974f 100644
--- a/functest/cli/commands/cli_os.py
+++ b/functest/cli/commands/cli_os.py
@@ -12,23 +12,21 @@ import os
import click
+from functest.utils.constants import CONST
import functest.utils.functest_utils as ft_utils
import functest.utils.openstack_clean as os_clean
import functest.utils.openstack_snapshot as os_snapshot
-import functest.utils.functest_constants as ft_constants
-
-
-OPENSTACK_RC_FILE = ft_constants.OPENSTACK_CREDS
-OPENSTACK_SNAPSHOT_FILE = ft_constants.OPENSTACK_SNAPSHOT_FILE
class CliOpenStack:
def __init__(self):
- self.os_auth_url = ft_constants.OS_AUTH_URL
+ self.os_auth_url = CONST.OS_AUTH_URL
self.endpoint_ip = None
self.endpoint_port = None
- if self.os_auth_url is not None:
+ self.openstack_creds = CONST.openstack_creds
+ self.snapshot_file = CONST.openstack_snapshot_file
+ if self.os_auth_url:
self.endpoint_ip = self.os_auth_url.rsplit("/")[2].rsplit(":")[0]
self.endpoint_port = self.os_auth_url.rsplit("/")[2].rsplit(":")[1]
@@ -43,13 +41,14 @@ class CliOpenStack:
click.echo("Cannot talk to the endpoint %s\n" % self.endpoint_ip)
exit(0)
- def show_credentials(self):
+ @staticmethod
+ def show_credentials():
for key, value in os.environ.items():
if key.startswith('OS_'):
click.echo("{}={}".format(key, value))
def fetch_credentials(self):
- if os.path.isfile(OPENSTACK_RC_FILE):
+ if os.path.isfile(self.openstack_creds):
answer = raw_input("It seems the RC file is already present. "
"Do you want to overwrite it? [y|n]\n")
while True:
@@ -60,31 +59,31 @@ class CliOpenStack:
else:
answer = raw_input("Invalid answer. Please type [y|n]\n")
- CI_INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
- if CI_INSTALLER_TYPE is None:
+ installer_type = CONST.INSTALLER_TYPE
+ if installer_type is None:
click.echo("The environment variable 'INSTALLER_TYPE' is not"
"defined. Please export it")
- CI_INSTALLER_IP = ft_constants.CI_INSTALLER_IP
- if CI_INSTALLER_IP is None:
+ installer_ip = CONST.INSTALLER_IP
+ if installer_ip is None:
click.echo("The environment variable 'INSTALLER_IP' is not"
"defined. Please export it")
cmd = ("%s/releng/utils/fetch_os_creds.sh -d %s -i %s -a %s"
- % (ft_constants.REPOS_DIR,
- OPENSTACK_RC_FILE,
- CI_INSTALLER_TYPE,
- CI_INSTALLER_IP))
+ % (CONST.dir_repos,
+ self.openstack_creds,
+ installer_type,
+ installer_ip))
click.echo("Fetching credentials from installer node '%s' with IP=%s.."
- % (CI_INSTALLER_TYPE, CI_INSTALLER_IP))
+ % (installer_type, installer_ip))
ft_utils.execute_command(cmd, verbose=False)
def check(self):
self.ping_endpoint()
- cmd = ft_constants.FUNCTEST_REPO_DIR + "/functest/ci/check_os.sh"
+ cmd = CONST.dir_repo_functest + "/functest/ci/check_os.sh"
ft_utils.execute_command(cmd, verbose=False)
def snapshot_create(self):
self.ping_endpoint()
- if os.path.isfile(OPENSTACK_SNAPSHOT_FILE):
+ if os.path.isfile(self.snapshot_file):
answer = raw_input("It seems there is already an OpenStack "
"snapshot. Do you want to overwrite it with "
"the current OpenStack status? [y|n]\n")
@@ -100,18 +99,18 @@ class CliOpenStack:
os_snapshot.main()
def snapshot_show(self):
- if not os.path.isfile(OPENSTACK_SNAPSHOT_FILE):
+ if not os.path.isfile(self.snapshot_file):
click.echo("There is no OpenStack snapshot created. To create "
"one run the command "
"'functest openstack snapshot-create'")
return
- with open(OPENSTACK_SNAPSHOT_FILE, 'r') as yaml_file:
+ with open(self.snapshot_file, 'r') as yaml_file:
click.echo("\n%s"
% yaml_file.read())
def clean(self):
self.ping_endpoint()
- if not os.path.isfile(OPENSTACK_SNAPSHOT_FILE):
+ if not os.path.isfile(self.snapshot_file):
click.echo("Not possible to clean OpenStack without a snapshot. "
"This could cause problems. "
"Run first the command "
diff --git a/functest/cli/commands/cli_testcase.py b/functest/cli/commands/cli_testcase.py
index 70a77a142..b6566245a 100644
--- a/functest/cli/commands/cli_testcase.py
+++ b/functest/cli/commands/cli_testcase.py
@@ -14,19 +14,17 @@ import os
import click
import functest.ci.tier_builder as tb
+from functest.utils.constants import CONST
import functest.utils.functest_utils as ft_utils
import functest.utils.functest_vacation as vacation
-import functest.utils.functest_constants as ft_constants
class CliTestcase:
def __init__(self):
- CI_INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
- CI_SCENARIO = ft_constants.CI_SCENARIO
- testcases = ft_constants.FUNCTEST_TESTCASES_YAML
-
- self.tiers = tb.TierBuilder(CI_INSTALLER_TYPE, CI_SCENARIO, testcases)
+ self.tiers = tb.TierBuilder(CONST.INSTALLER_TYPE,
+ CONST.DEPLOY_SCENARIO,
+ CONST.functest_testcases_yaml)
def list(self):
summary = ""
@@ -43,19 +41,23 @@ class CliTestcase:
click.echo(description)
- def run(self, testname, noclean=False):
+ @staticmethod
+ def run(testname, noclean=False, report=False):
+
+ flags = ""
+ if noclean:
+ flags += "-n "
+ if report:
+ flags += "-r "
+
if testname == 'vacation':
vacation.main()
- elif not os.path.isfile(ft_constants.ENV_FILE):
+ elif not os.path.isfile(CONST.env_active):
click.echo("Functest environment is not ready. "
"Run first 'functest env prepare'")
else:
tests = testname.split(",")
for test in tests:
- if noclean:
- cmd = ("python %s/functest/ci/run_tests.py "
- "-n -t %s" % (ft_constants.FUNCTEST_REPO_DIR, test))
- else:
- cmd = ("python %s/functest/ci/run_tests.py "
- "-t %s" % (ft_constants.FUNCTEST_REPO_DIR, test))
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, flags, test))
ft_utils.execute_command(cmd)
diff --git a/functest/cli/commands/cli_tier.py b/functest/cli/commands/cli_tier.py
index 9da51072a..b9d25b6d0 100644
--- a/functest/cli/commands/cli_tier.py
+++ b/functest/cli/commands/cli_tier.py
@@ -14,17 +14,16 @@ import os
import click
import functest.ci.tier_builder as tb
+from functest.utils.constants import CONST
import functest.utils.functest_utils as ft_utils
-import functest.utils.functest_constants as ft_constants
class CliTier:
def __init__(self):
- CI_INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
- CI_SCENARIO = ft_constants.CI_SCENARIO
- testcases = ft_constants.FUNCTEST_TESTCASES_YAML
- self.tiers = tb.TierBuilder(CI_INSTALLER_TYPE, CI_SCENARIO, testcases)
+ self.tiers = tb.TierBuilder(CONST.INSTALLER_TYPE,
+ CONST.DEPLOY_SCENARIO,
+ CONST.functest_testcases_yaml)
def list(self):
summary = ""
@@ -54,15 +53,19 @@ class CliTier:
tests = tier.get_test_names()
click.echo("Test cases in tier '%s':\n %s\n" % (tiername, tests))
- def run(self, tiername, noclean=False):
- if not os.path.isfile(ft_constants.ENV_FILE):
+ @staticmethod
+ def run(tiername, noclean=False, report=False):
+
+ flags = ""
+ if noclean:
+ flags += "-n "
+ if report:
+ flags += "-r "
+
+ if not os.path.isfile(CONST.env_active):
click.echo("Functest environment is not ready. "
"Run first 'functest env prepare'")
else:
- if noclean:
- cmd = ("python %s/functest/ci/run_tests.py "
- "-n -t %s" % (ft_constants.FUNCTEST_REPO_DIR, tiername))
- else:
- cmd = ("python %s/functest/ci/run_tests.py "
- "-t %s" % (ft_constants.FUNCTEST_REPO_DIR, tiername))
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, flags, tiername))
ft_utils.execute_command(cmd)
diff --git a/functest/core/feature_base.py b/functest/core/feature_base.py
index 01a27f305..873e21dae 100644
--- a/functest/core/feature_base.py
+++ b/functest/core/feature_base.py
@@ -3,6 +3,7 @@ import time
import testcase_base as base
import functest.utils.functest_utils as ft_utils
import functest.utils.functest_logger as ft_logger
+from functest.utils.constants import CONST
class FeatureBase(base.TestcaseBase):
@@ -11,7 +12,7 @@ class FeatureBase(base.TestcaseBase):
self.project_name = project
self.case_name = case
self.cmd = cmd
- self.repo = self.get_conf('general.directories.{}'.format(repo))
+ self.repo = CONST.__getattribute__(repo)
self.result_file = self.get_result_file()
self.logger = ft_logger.Logger(project).getLogger()
@@ -44,15 +45,10 @@ class FeatureBase(base.TestcaseBase):
return exit_code
def get_result_file(self):
- dir = self.get_conf('general.directories.dir_results')
- return "{}/{}.log".format(dir, self.project_name)
+ return "{}/{}.log".format(CONST.dir_results, self.project_name)
def log_results(self):
ft_utils.logger_test_results(self.project_name,
self.case_name,
self.criteria,
self.details)
-
- @staticmethod
- def get_conf(parameter):
- return ft_utils.get_functest_config(parameter)
diff --git a/functest/core/testcase_base.py b/functest/core/testcase_base.py
index 838b63983..ec46bc643 100644
--- a/functest/core/testcase_base.py
+++ b/functest/core/testcase_base.py
@@ -9,6 +9,7 @@
import os
+from functest.utils.constants import CONST
import functest.utils.functest_logger as ft_logger
import functest.utils.functest_utils as ft_utils
@@ -17,7 +18,7 @@ class TestcaseBase(object):
EX_OK = os.EX_OK
EX_RUN_ERROR = os.EX_SOFTWARE
- EX_PUSH_TO_DB_ERROR = os.EX_SOFTWARE - 1
+ EX_PUBLISH_RESULT_FAILED = os.EX_SOFTWARE - 1
EX_TESTCASE_FAILED = os.EX_SOFTWARE - 2
logger = ft_logger.Logger(__name__).getLogger()
@@ -43,21 +44,45 @@ class TestcaseBase(object):
self.logger.error("Run must be implemented")
return TestcaseBase.EX_RUN_ERROR
- def push_to_db(self):
+ def publish_report(self):
+ if "RESULTS_STORE" in os.environ:
+ CONST.results_test_db_url = os.environ['RESULTS_STORE']
+
try:
assert self.project_name
assert self.case_name
assert self.criteria
assert self.start_time
assert self.stop_time
- if ft_utils.push_results_to_db(
- self.project_name, self.case_name, self.start_time,
- self.stop_time, self.criteria, self.details):
- self.logger.info("The results were successfully pushed to DB")
- return TestcaseBase.EX_OK
+ if CONST.results_test_db_url.lower().startswith(
+ ("http://", "https://")):
+ self.push_to_db()
+ elif CONST.results_test_db_url.lower().startswith("file://"):
+ self.write_to_file()
else:
- self.logger.error("The results cannot be pushed to DB")
- return TestcaseBase.EX_PUSH_TO_DB_ERROR
+ self.logger.error("Please check parameter test_db_url and "
+ "OS environ variable RESTULTS_STORE")
+ return TestcaseBase.EX_PUBLISH_RESULT_FAILED
except Exception:
- self.logger.exception("The results cannot be pushed to DB")
- return TestcaseBase.EX_PUSH_TO_DB_ERROR
+ self.logger.exception("The results cannot be stored")
+ return TestcaseBase.EX_PUBLISH_RESULT_FAILED
+
+ def write_to_file(self):
+ if ft_utils.write_results_to_file(
+ self.project_name, self.case_name, self.start_time,
+ self.stop_time, self.criteria, self.details):
+ self.logger.info("The results were successfully written to a file")
+ return TestcaseBase.EX_OK
+ else:
+ self.logger.error("write results to a file failed")
+ return TestcaseBase.EX_PUBLISH_RESULT_FAILED
+
+ def push_to_db(self):
+ if ft_utils.push_results_to_db(
+ self.project_name, self.case_name, self.start_time,
+ self.stop_time, self.criteria, self.details):
+ self.logger.info("The results were successfully pushed to DB")
+ return TestcaseBase.EX_OK
+ else:
+ self.logger.error("The results cannot be pushed to DB")
+ return TestcaseBase.EX_PUBLISH_RESULT_FAILED
diff --git a/functest/core/vnf_base.py b/functest/core/vnf_base.py
new file mode 100644
index 000000000..4d019858a
--- /dev/null
+++ b/functest/core/vnf_base.py
@@ -0,0 +1,248 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2016 Orange 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
+
+import os
+import time
+
+import inspect
+
+
+import functest.utils.functest_logger as ft_logger
+import functest.utils.openstack_utils as os_utils
+import functest.utils.functest_utils as ft_utils
+import testcase_base as base
+from functest.utils.constants import CONST
+
+
+class VnfOnBoardingBase(base.TestcaseBase):
+
+ logger = ft_logger.Logger(__name__).getLogger()
+
+ def __init__(self, project='functest', case='', repo='', cmd=''):
+ super(VnfOnBoardingBase, self).__init__()
+ self.repo = repo
+ self.project_name = project
+ self.case_name = case
+ self.cmd = cmd
+ self.details = {}
+ self.data_dir = CONST.dir_functest_data
+ self.details['orchestrator'] = {}
+ self.details['vnf'] = {}
+ self.details['test_vnf'] = {}
+ self.images = {}
+ try:
+ self.tenant_name = CONST.__getattribute__(
+ 'vnf_{}_tenant_name'.format(self.case_name))
+ self.tenant_description = CONST.__getattribute__(
+ 'vnf_{}_tenant_description'.format(self.case_name))
+ except:
+ raise Exception("Unknown VNF case=" + self.case_name)
+
+ try:
+ self.images = CONST.__getattribute__(
+ 'vnf_{}_tenant_images'.format(self.case_name))
+ except:
+ self.logger.warn("No tenant image defined for this VNF")
+
+ def execute(self):
+ self.start_time = time.time()
+ # Prepare the test (Create Tenant, User, ...)
+ self.logger.info("Create VNF Onboarding environment")
+ self.prepare()
+
+ # Deploy orchestrator
+ try:
+ self.logger.info("Deploy orchestrator (if necessary)")
+ orchestrator_ready_time = time.time()
+ res_orchestrator = self.deploy_orchestrator()
+ # orchestrator is not mandatory
+ if res_orchestrator is not None:
+ self.details['orchestrator']['status'] = (
+ res_orchestrator['status'])
+ self.details['orchestrator']['result'] = (
+ res_orchestrator['result'])
+ self.details['orchestrator']['duration'] = round(
+ orchestrator_ready_time - self.start_time, 1)
+ except:
+ self.logger.warn("Problem with the Orchestrator")
+
+ # Deploy VNF
+ try:
+ self.logger.info("Deploy VNF " + self.case_name)
+ res_deploy_vnf = self.deploy_vnf()
+ vnf_ready_time = time.time()
+ self.details['vnf']['status'] = res_deploy_vnf['status']
+ self.details['vnf']['result'] = res_deploy_vnf['result']
+ self.details['vnf']['duration'] = round(
+ vnf_ready_time - orchestrator_ready_time, 1)
+ except:
+ raise Exception("Error during VNF deployment")
+
+ # Test VNF
+ try:
+ self.logger.info("Test VNF")
+ res_test_vnf = self.test_vnf()
+ test_vnf_done_time = time.time()
+ self.details['test_vnf']['status'] = res_test_vnf['status']
+ self.details['test_vnf']['result'] = res_test_vnf['result']
+ self.details['test_vnf']['duration'] = round(
+ test_vnf_done_time - vnf_ready_time, 1)
+ except:
+ raise Exception("Error when running VNF tests")
+
+ # Clean the system
+ self.clean()
+ self.stop_time = time.time()
+
+ exit_code = self.parse_results()
+ self.log_results()
+ return exit_code
+
+ # prepare state could consist in the creation of the resources
+ # a dedicated user
+ # a dedictaed tenant
+ # dedicated images
+ def prepare(self):
+ self.creds = os_utils.get_credentials()
+ self.keystone_client = os_utils.get_keystone_client()
+
+ self.logger.info("Prepare OpenStack plateform(create tenant and user)")
+ user_id = os_utils.get_user_id(self.keystone_client,
+ self.creds['username'])
+ if user_id == '':
+ self.step_failure("Failed to get id of " +
+ self.creds['username'])
+
+ tenant_id = os_utils.create_tenant(
+ self.keystone_client, self.tenant_name, self.tenant_description)
+ if not tenant_id:
+ self.step_failure("Failed to create " +
+ self.tenant_name + " tenant")
+
+ roles_name = ["admin", "Admin"]
+ role_id = ''
+ for role_name in roles_name:
+ if role_id == '':
+ role_id = os_utils.get_role_id(self.keystone_client, role_name)
+
+ if role_id == '':
+ self.logger.error("Failed to get id for %s role" % role_name)
+ self.step_failure("Failed to get role id of " + role_name)
+
+ if not os_utils.add_role_user(self.keystone_client, user_id,
+ role_id, tenant_id):
+ self.logger.error("Failed to add %s on tenant" %
+ self.creds['username'])
+ self.step_failure("Failed to add %s on tenant" %
+ self.creds['username'])
+
+ user_id = os_utils.create_user(self.keystone_client,
+ self.tenant_name,
+ self.tenant_name,
+ None,
+ tenant_id)
+ if not user_id:
+ self.logger.error("Failed to create %s user" % self.tenant_name)
+ self.step_failure("Failed to create user ")
+
+ self.logger.info("Update OpenStack creds informations")
+ self.creds.update({
+ "tenant": self.tenant_name,
+ })
+ self.neutron_client = os_utils.get_neutron_client(self.creds)
+ self.nova_client = os_utils.get_nova_client(self.creds)
+ self.creds.update({
+ "username": self.tenant_name,
+ "password": self.tenant_name,
+ })
+ self.glance_client = os_utils.get_glance_client(self.creds)
+ self.logger.info("Upload some OS images if it doesn't exist")
+
+ temp_dir = os.path.join(self.data_dir, "tmp/")
+ for image_name, image_url in self.images.iteritems():
+ image_id = os_utils.get_image_id(self.glance_client, image_name)
+
+ if image_id == '':
+ self.logger.info("""%s image doesn't exist on glance repository. Try
+ downloading this image and upload on glance !""" % image_name)
+ image_id = os_utils.download_and_add_image_on_glance(
+ self.glance_client, image_name, image_url, temp_dir)
+
+ if image_id == '':
+ self.step_failure(
+ "Failed to find or upload required OS "
+ "image for this deployment")
+
+ self.logger.info("Update security group quota for this tenant")
+
+ if not os_utils.update_sg_quota(self.neutron_client,
+ tenant_id, 50, 100):
+ self.step_failure("Failed to update security group quota" +
+ " for tenant " + self.tenant_name)
+
+ # orchestrator is not mandatory to dpeloy and test VNF
+ def deploy_orchestrator(self, **kwargs):
+ pass
+
+ # TODO see how to use built-in exception from releng module
+ def deploy_vnf(self):
+ self.logger.error("VNF must be deployed")
+ raise Exception("VNF not deployed")
+
+ def test_vnf(self):
+ self.logger.error("VNF must be tested")
+ raise Exception("VNF not tested")
+
+ def clean(self):
+ self.logger.info("test cleaning")
+
+ self.logger.info("Removing %s tenant .." % self.tenant_name)
+ tenant_id = os_utils.get_tenant_id(self.keystone_client,
+ self.tenant_name)
+ if tenant_id == '':
+ self.logger.error("Error : Failed to get id of %s tenant" %
+ self.tenant_name)
+ else:
+ if not os_utils.delete_tenant(self.keystone_client, tenant_id):
+ self.logger.error("Error : Failed to remove %s tenant" %
+ self.tenant_name)
+
+ self.logger.info("Removing %s user .." % self.tenant_name)
+ user_id = os_utils.get_user_id(
+ self.keystone_client, self.tenant_name)
+ if user_id == '':
+ self.logger.error("Error : Failed to get id of %s user" %
+ self.tenant_name)
+ else:
+ if not os_utils.delete_user(self.keystone_client, user_id):
+ self.logger.error("Error : Failed to remove %s user" %
+ self.tenant_name)
+
+ def parse_results(self):
+ exit_code = self.EX_OK
+ self.criteria = "PASS"
+ self.logger.info(self.details)
+ # The 2 VNF steps must be OK to get a PASS result
+ if (self.details['vnf']['status'] is not "PASS" or
+ self.details['test_vnf']['status'] is not "PASS"):
+ exit_code = self.EX_RUN_ERROR
+ self.criteria = "FAIL"
+ return exit_code
+
+ def log_results(self):
+ ft_utils.logger_test_results(self.project_name,
+ self.case_name,
+ self.criteria,
+ self.details)
+
+ def step_failure(self, error_msg):
+ part = inspect.stack()[1][3]
+ self.details[part]['status'] = 'FAIL'
+ self.details[part]['result'] = error_msg
+ raise Exception(error_msg)
diff --git a/functest/opnfv_tests/features/copper.py b/functest/opnfv_tests/features/copper.py
index 8d5393c95..a10364e26 100755
--- a/functest/opnfv_tests/features/copper.py
+++ b/functest/opnfv_tests/features/copper.py
@@ -22,4 +22,4 @@ class Copper(base.FeatureBase):
super(Copper, self).__init__(project='copper',
case='copper-notification',
repo='dir_repo_copper')
- self.cmd = "%s/tests/run.sh %s/tests" % (self.repo, self.repo)
+ self.cmd = 'bash %s/tests/run.sh' % self.repo
diff --git a/functest/opnfv_tests/features/domino.py b/functest/opnfv_tests/features/domino.py
index 341648f4b..b36220fa0 100755
--- a/functest/opnfv_tests/features/domino.py
+++ b/functest/opnfv_tests/features/domino.py
@@ -14,65 +14,12 @@
# 0.3: add report flag to push results when needed
# 0.4: refactoring to match Test abstraction class
-import argparse
-import os
-import sys
-import time
+import functest.core.feature_base as base
-import functest.core.testcase_base as testcase_base
-import functest.utils.functest_constants as ft_constants
-import functest.utils.functest_logger as ft_logger
-import functest.utils.functest_utils as ft_utils
-
-
-class DominoCases(testcase_base.TestcaseBase):
- DOMINO_REPO = ft_constants.DOMINO_REPO_DIR
- RESULTS_DIR = ft_constants.FUNCTEST_RESULTS_DIR
- logger = ft_logger.Logger("domino").getLogger()
+class Domino(base.FeatureBase):
def __init__(self):
- super(DominoCases, self).__init__()
- self.project_name = "domino"
- self.case_name = "domino-multinode"
-
- def main(self, **kwargs):
- cmd = 'cd %s && ./tests/run_multinode.sh' % self.DOMINO_REPO
- log_file = os.path.join(self.RESULTS_DIR, "domino.log")
- start_time = time.time()
-
- ret = ft_utils.execute_command(cmd,
- output_file=log_file)
-
- stop_time = time.time()
- if ret == 0:
- self.logger.info("domino OK")
- status = 'PASS'
- else:
- self.logger.info("domino FAILED")
- status = "FAIL"
-
- # report status only if tests run (FAIL OR PASS)
- self.criteria = status
- self.start_time = start_time
- self.stop_time = stop_time
- self.details = {}
-
- def run(self):
- kwargs = {}
- return self.main(**kwargs)
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser()
- parser.add_argument("-r", "--report",
- help="Create json result file",
- action="store_true")
- args = vars(parser.parse_args())
- domino = DominoCases()
- try:
- result = domino.main(**args)
- if result != testcase_base.TestcaseBase.EX_OK:
- sys.exit(result)
- if args['report']:
- sys.exit(domino.push_to_db())
- except Exception:
- sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)
+ super(Domino, self).__init__(project='domino',
+ case='domino-multinode',
+ repo='dir_repo_domino')
+ self.cmd = 'cd %s && ./tests/run_multinode.sh' % self.repo
diff --git a/functest/opnfv_tests/features/odl_sfc.py b/functest/opnfv_tests/features/odl_sfc.py
index b194b2840..3b68d4204 100644
--- a/functest/opnfv_tests/features/odl_sfc.py
+++ b/functest/opnfv_tests/features/odl_sfc.py
@@ -7,7 +7,6 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
#
-
import functest.core.feature_base as base
@@ -17,4 +16,5 @@ class OpenDaylightSFC(base.FeatureBase):
super(OpenDaylightSFC, self).__init__(project='sfc',
case='functest-odl-sfc"',
repo='dir_repo_sfc')
- self.cmd = 'cd %s/tests/functest && python ./run_tests.py' % self.repo
+ dir_sfc_functest = '{}/sfc/tests/functest'.format(self.repo)
+ self.cmd = 'cd %s && python ./run_tests.py' % dir_sfc_functest
diff --git a/functest/opnfv_tests/features/sdnvpn.py b/functest/opnfv_tests/features/sdnvpn.py
index 451299eb3..1919a03c2 100755
--- a/functest/opnfv_tests/features/sdnvpn.py
+++ b/functest/opnfv_tests/features/sdnvpn.py
@@ -7,70 +7,14 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
#
+import functest.core.feature_base as base
-import argparse
-import os
-import sys
-import time
-
-import functest.core.testcase_base as testcase_base
-import functest.utils.functest_constants as ft_constants
-import functest.utils.functest_logger as ft_logger
-import functest.utils.functest_utils as ft_utils
-
-
-class SdnVpnTests(testcase_base.TestcaseBase):
- SDNVPN_REPO_TESTS = os.path.join(
- ft_constants.SDNVPN_REPO_DIR, "tests/functest")
- logger = ft_logger.Logger("sdnvpn").getLogger()
+class SdnVpnTests(base.FeatureBase):
def __init__(self):
- super(SdnVpnTests, self).__init__()
- self.project_name = "sdnvpn"
- self.case_name = "bgpvpn"
-
- def main(self, **kwargs):
- os.chdir(self.SDNVPN_REPO_TESTS)
- cmd = 'run_tests.py'
- log_file = os.path.join(
- ft_constants.FUNCTEST_RESULTS_DIR, "sdnvpn.log")
- start_time = time.time()
-
- ret = ft_utils.execute_command(cmd,
- output_file=log_file)
-
- stop_time = time.time()
- if ret == 0:
- self.logger.info("%s OK" % self.case_name)
- status = 'PASS'
- else:
- self.logger.info("%s FAILED" % self.case_name)
- status = "FAIL"
-
- # report status only if tests run (FAIL OR PASS)
- self.criteria = status
- self.start_time = start_time
- self.stop_time = stop_time
- self.details = {}
-
- def run(self):
- kwargs = {}
- return self.main(**kwargs)
-
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser()
- parser.add_argument("-r", "--report",
- help="Create json result file",
- action="store_true")
- args = vars(parser.parse_args())
- sdnvpn = SdnVpnTests()
- try:
- result = sdnvpn.main(**args)
- if result != testcase_base.TestcaseBase.EX_OK:
- sys.exit(result)
- if args['report']:
- sys.exit(sdnvpn.push_to_db())
- except Exception:
- sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)
+ super(SdnVpnTests, self).__init__(project='sdnvpn',
+ case='bgpvpn',
+ repo='dir_repo_sdnvpn')
+ dir_sfc_functest = '{}/sdnvpn/test/functest'.format(self.repo)
+ self.cmd = 'cd %s && python ./run_tests.py' % dir_sfc_functest
diff --git a/functest/opnfv_tests/mano/orchestra.py b/functest/opnfv_tests/mano/orchestra.py
new file mode 100755
index 000000000..fd5e40d05
--- /dev/null
+++ b/functest/opnfv_tests/mano/orchestra.py
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import functest.core.feature_base as base
+
+
+class Orchestra(base.FeatureBase):
+ def __init__(self):
+ super(Orchestra, self).__init__(project='orchestra',
+ case='orchestra',
+ repo='dir_repo_orchestra')
+ # TODO
+ # self.cmd = "%s/tests/run.sh %s/tests" % (self.repo, self.repo)
diff --git a/functest/opnfv_tests/openstack/examples/create_instance_and_ip.py b/functest/opnfv_tests/openstack/examples/create_instance_and_ip.py
index 4a9ff713b..b44008642 100755
--- a/functest/opnfv_tests/openstack/examples/create_instance_and_ip.py
+++ b/functest/opnfv_tests/openstack/examples/create_instance_and_ip.py
@@ -14,9 +14,9 @@ import argparse
import os
import sys
+from functest.utils.constants import CONST
import functest.utils.functest_logger as ft_logger
import functest.utils.openstack_utils as os_utils
-import functest.utils.functest_constants as ft_constants
parser = argparse.ArgumentParser()
@@ -29,26 +29,26 @@ args = parser.parse_args()
""" logging configuration """
logger = ft_logger.Logger("create_instance_and_ip").getLogger()
-HOME = ft_constants.HOME + "/"
+HOME = CONST.dir_home + "/"
VM_BOOT_TIMEOUT = 180
-EXAMPLE_INSTANCE_NAME = ft_constants.EXAMPLE_INSTANCE_NAME
-EXAMPLE_FLAVOR = ft_constants.EXAMPLE_FLAVOR
-EXAMPLE_IMAGE_NAME = ft_constants.EXAMPLE_IMAGE_NAME
-IMAGE_FILENAME = ft_constants.GLANCE_IMAGE_FILENAME
-IMAGE_FORMAT = ft_constants.GLANCE_IMAGE_FORMAT
-IMAGE_PATH = os.path.join(ft_constants.FUNCTEST_DATA_DIR, IMAGE_FILENAME)
+EXAMPLE_INSTANCE_NAME = CONST.example_vm_name
+EXAMPLE_FLAVOR = CONST.example_flavor
+EXAMPLE_IMAGE_NAME = CONST.example_image_name
+IMAGE_FILENAME = CONST.openstack_image_file_name
+IMAGE_FORMAT = CONST.openstack_image_disk_format
+IMAGE_PATH = os.path.join(CONST.dir_functest_data, IMAGE_FILENAME)
# NEUTRON Private Network parameters
-EXAMPLE_PRIVATE_NET_NAME = ft_constants.EXAMPLE_PRIVATE_NET_NAME
-EXAMPLE_PRIVATE_SUBNET_NAME = ft_constants.EXAMPLE_PRIVATE_SUBNET_NAME
-EXAMPLE_PRIVATE_SUBNET_CIDR = ft_constants.EXAMPLE_PRIVATE_SUBNET_CIDR
-EXAMPLE_ROUTER_NAME = ft_constants.EXAMPLE_ROUTER_NAME
+EXAMPLE_PRIVATE_NET_NAME = CONST.example_private_net_name
+EXAMPLE_PRIVATE_SUBNET_NAME = CONST.example_private_subnet_name
+EXAMPLE_PRIVATE_SUBNET_CIDR = CONST.example_private_subnet_cidr
+EXAMPLE_ROUTER_NAME = CONST.example_router_name
-EXAMPLE_SECGROUP_NAME = ft_constants.EXAMPLE_SECGROUP_NAME
-EXAMPLE_SECGROUP_DESCR = ft_constants.EXAMPLE_SECGROUP_DESCR
+EXAMPLE_SECGROUP_NAME = CONST.example_sg_name
+EXAMPLE_SECGROUP_DESCR = CONST.example_sg_desc
def main():
diff --git a/functest/opnfv_tests/openstack/healthcheck/healthcheck.sh b/functest/opnfv_tests/openstack/healthcheck/healthcheck.sh
index e27cf4b4b..57aa0c707 100755
--- a/functest/opnfv_tests/openstack/healthcheck/healthcheck.sh
+++ b/functest/opnfv_tests/openstack/healthcheck/healthcheck.sh
@@ -228,10 +228,11 @@ sleep ${wait_time}
# Check if flavor exists
-if [[ -z $(nova flavor-list|grep $flavor) ]]; then
+if [[ -z $(openstack flavor list -f value -c Name | fgrep -x $flavor) ]]; then
# if given flavor doesn't exist, we create one
debug "Flavor $flavor doesn't exist. Creating a new flavor."
- nova flavor-create --is-public false ${flavor} auto 512 1 1 --is-public True
+ openstack flavor create ${flavor} --id auto --ram 512 --disk 1 --vcpus 1
+ openstack flavor set ${flavor} --property hw:mem_page_size=any
fi
debug "Using flavor $flavor to boot the instances."
diff --git a/functest/opnfv_tests/openstack/rally/run_rally-cert.py b/functest/opnfv_tests/openstack/rally/run_rally-cert.py
index 6d8f01602..b02fd4270 100755
--- a/functest/opnfv_tests/openstack/rally/run_rally-cert.py
+++ b/functest/opnfv_tests/openstack/rally/run_rally-cert.py
@@ -1,34 +1,27 @@
-#!/usr/bin/env python
+#!/usr/bin/python
#
-# Copyright (c) 2015 Orange
-# guyrodrigue.koffi@orange.com
-# morgan.richomme@orange.com
-# All rights reserved. This program and the accompanying materials
+# 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
#
-# 0.1 (05/2015) initial commit
-# 0.2 (28/09/2015) extract Tempest, format json result, add ceilometer suite
-# 0.3 (19/10/2015) remove Tempest from run_rally
-# and push result into test DB
+# http://www.apache.org/licenses/LICENSE-2.0
#
-""" tests configuration """
+import argparse
import json
import os
import re
import subprocess
import time
-import argparse
import iniparse
import yaml
+from functest.utils.constants import CONST
import functest.utils.functest_logger as ft_logger
import functest.utils.functest_utils as ft_utils
import functest.utils.openstack_utils as os_utils
-import functest.utils.functest_constants as ft_constants
tests = ['authenticate', 'glance', 'cinder', 'heat', 'keystone',
'neutron', 'nova', 'quotas', 'requests', 'vm', 'all']
@@ -71,8 +64,7 @@ else:
""" logging configuration """
logger = ft_logger.Logger("run_rally-cert").getLogger()
-RALLY_DIR = os.path.join(ft_constants.FUNCTEST_REPO_DIR,
- ft_constants.RALLY_RELATIVE_PATH)
+RALLY_DIR = os.path.join(CONST.dir_repo_functest, CONST.dir_rally)
RALLY_SCENARIO_DIR = os.path.join(RALLY_DIR, "scenario")
SANITY_MODE_DIR = os.path.join(RALLY_SCENARIO_DIR, "sanity")
FULL_MODE_DIR = os.path.join(RALLY_SCENARIO_DIR, "full")
@@ -87,19 +79,19 @@ TENANTS_AMOUNT = 3
ITERATIONS_AMOUNT = 10
CONCURRENCY = 4
-RESULTS_DIR = os.path.join(ft_constants.FUNCTEST_RESULTS_DIR, 'rally')
-TEMPEST_CONF_FILE = os.path.join(ft_constants.FUNCTEST_RESULTS_DIR,
+RESULTS_DIR = os.path.join(CONST.dir_results, 'rally')
+TEMPEST_CONF_FILE = os.path.join(CONST.dir_results,
'tempest/tempest.conf')
-RALLY_PRIVATE_NET_NAME = ft_constants.RALLY_PRIVATE_NET_NAME
-RALLY_PRIVATE_SUBNET_NAME = ft_constants.RALLY_PRIVATE_SUBNET_NAME
-RALLY_PRIVATE_SUBNET_CIDR = ft_constants.RALLY_PRIVATE_SUBNET_CIDR
-RALLY_ROUTER_NAME = ft_constants.RALLY_ROUTER_NAME
+RALLY_PRIVATE_NET_NAME = CONST.rally_network_name
+RALLY_PRIVATE_SUBNET_NAME = CONST.rally_subnet_name
+RALLY_PRIVATE_SUBNET_CIDR = CONST.rally_subnet_cidr
+RALLY_ROUTER_NAME = CONST.rally_router_name
-GLANCE_IMAGE_NAME = ft_constants.GLANCE_IMAGE_NAME
-GLANCE_IMAGE_FILENAME = ft_constants.GLANCE_IMAGE_FILENAME
-GLANCE_IMAGE_FORMAT = ft_constants.GLANCE_IMAGE_FORMAT
-GLANCE_IMAGE_PATH = os.path.join(ft_constants.FUNCTEST_DATA_DIR,
+GLANCE_IMAGE_NAME = CONST.openstack_image_name
+GLANCE_IMAGE_FILENAME = CONST.openstack_image_file_name
+GLANCE_IMAGE_FORMAT = CONST.openstack_image_disk_format
+GLANCE_IMAGE_PATH = os.path.join(CONST.dir_functest_data,
GLANCE_IMAGE_FILENAME)
CINDER_VOLUME_TYPE_NAME = "volume_test"
@@ -181,7 +173,7 @@ def build_task_args(test_file_name):
net_id = GlobalVariables.network_dict['net_id']
task_args['netid'] = str(net_id)
- auth_url = ft_constants.OS_AUTH_URL
+ auth_url = CONST.OS_AUTH_URL
if auth_url is not None:
task_args['request_url'] = auth_url.rsplit(":", 1)[0]
else:
@@ -271,8 +263,8 @@ def excl_scenario():
with open(BLACKLIST_FILE, 'r') as black_list_file:
black_list_yaml = yaml.safe_load(black_list_file)
- installer_type = ft_constants.CI_INSTALLER_TYPE
- deploy_scenario = ft_constants.CI_SCENARIO
+ installer_type = CONST.INSTALLER_TYPE
+ deploy_scenario = CONST.DEPLOY_SCENARIO
if (bool(installer_type) * bool(deploy_scenario)):
if 'scenario' in black_list_yaml.keys():
for item in black_list_yaml['scenario']:
@@ -392,10 +384,11 @@ def run_task(test_name):
logger.info('No tests for scenario "{}"'.format(test_name))
return
- cmd_line = ("rally task start --abort-on-sla-failure " +
- "--task {} ".format(task_file) +
- "--task-args \"{}\" ".format(build_task_args(test_name)))
- logger.debug('running command line : {}'.format(cmd_line))
+ cmd_line = ("rally task start --abort-on-sla-failure "
+ "--task {0} "
+ "--task-args \"{1}\""
+ .format(task_file, build_task_args(test_name)))
+ logger.debug('running command line: {}'.format(cmd_line))
p = subprocess.Popen(cmd_line, stdout=subprocess.PIPE,
stderr=RALLY_STDERR, shell=True)
@@ -405,10 +398,11 @@ def run_task(test_name):
if task_id is None:
logger.error('Failed to retrieve task_id, validating task...')
- cmd_line = ("rally task validate " +
- "--task {} ".format(task_file) +
- "--task-args \"{}\" ".format(build_task_args(test_name)))
- logger.debug('running command line : {}'.format(cmd_line))
+ cmd_line = ("rally task validate "
+ "--task {0} "
+ "--task-args \"{1}\""
+ .format(task_file, build_task_args(test_name)))
+ logger.debug('running command line: {}'.format(cmd_line))
p = subprocess.Popen(cmd_line, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, shell=True)
output = get_cmd_output(p)
@@ -426,12 +420,12 @@ def run_task(test_name):
cmd_line = "rally task report {} --out {}".format(task_id,
report_html_dir)
- logger.debug('running command line : {}'.format(cmd_line))
+ logger.debug('running command line: {}'.format(cmd_line))
os.popen(cmd_line)
# get and save rally operation JSON result
cmd_line = "rally task results %s" % task_id
- logger.debug('running command line : {}'.format(cmd_line))
+ logger.debug('running command line: {}'.format(cmd_line))
cmd = os.popen(cmd_line)
json_results = cmd.read()
report_json_name = 'opnfv-{}.json'.format(test_name)
diff --git a/functest/opnfv_tests/openstack/snaps/api_check.py b/functest/opnfv_tests/openstack/snaps/api_check.py
index 278892094..17d05b922 100644
--- a/functest/opnfv_tests/openstack/snaps/api_check.py
+++ b/functest/opnfv_tests/openstack/snaps/api_check.py
@@ -5,11 +5,13 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
-import functest.utils.functest_utils as ft_utils
+import unittest
+
+from snaps import test_suite_builder
+
from functest.core.pytest_suite_runner import PyTestSuiteRunner
from functest.opnfv_tests.openstack.snaps import snaps_utils
-from snaps import test_suite_builder
-import unittest
+from functest.utils.constants import CONST
class ApiCheck(PyTestSuiteRunner):
@@ -23,10 +25,10 @@ class ApiCheck(PyTestSuiteRunner):
self.suite = unittest.TestSuite()
self.case_name = "api_check"
- creds_file = ft_utils.get_functest_config('general.openstack.creds')
- use_key = ft_utils.get_functest_config('snaps.use_keystone')
ext_net_name = snaps_utils.get_ext_net_name()
- test_suite_builder.add_openstack_api_tests(self.suite, creds_file,
- ext_net_name,
- use_keystone=use_key)
+ test_suite_builder.add_openstack_api_tests(
+ self.suite,
+ CONST.openstack_creds,
+ ext_net_name,
+ use_keystone=CONST.snaps_use_keystone)
diff --git a/functest/opnfv_tests/openstack/snaps/connection_check.py b/functest/opnfv_tests/openstack/snaps/connection_check.py
index c2f5b1027..11f8ad074 100644
--- a/functest/opnfv_tests/openstack/snaps/connection_check.py
+++ b/functest/opnfv_tests/openstack/snaps/connection_check.py
@@ -5,11 +5,13 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
-import functest.utils.functest_utils as ft_utils
+import unittest
+
+from snaps import test_suite_builder
+
from functest.core.pytest_suite_runner import PyTestSuiteRunner
from functest.opnfv_tests.openstack.snaps import snaps_utils
-from snaps import test_suite_builder
-import unittest
+from functest.utils.constants import CONST
class ConnectionCheck(PyTestSuiteRunner):
@@ -23,10 +25,10 @@ class ConnectionCheck(PyTestSuiteRunner):
self.suite = unittest.TestSuite()
self.case_name = "connection_check"
- creds_file = ft_utils.get_functest_config('general.openstack.creds')
- use_key = ft_utils.get_functest_config('snaps.use_keystone')
ext_net_name = snaps_utils.get_ext_net_name()
- test_suite_builder.add_openstack_client_tests(self.suite, creds_file,
- ext_net_name,
- use_keystone=use_key)
+ test_suite_builder.add_openstack_client_tests(
+ self.suite,
+ CONST.openstack_creds,
+ ext_net_name,
+ use_keystone=CONST.snaps_use_keystone)
diff --git a/functest/opnfv_tests/openstack/snaps/smoke.py b/functest/opnfv_tests/openstack/snaps/smoke.py
index f66c17ff2..83eb6600c 100644
--- a/functest/opnfv_tests/openstack/snaps/smoke.py
+++ b/functest/opnfv_tests/openstack/snaps/smoke.py
@@ -5,12 +5,14 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
-import functest.utils.functest_utils as ft_utils
+import os
+import unittest
+
+from snaps import test_suite_builder
+
from functest.core.pytest_suite_runner import PyTestSuiteRunner
from functest.opnfv_tests.openstack.snaps import snaps_utils
-from snaps import test_suite_builder
-import unittest
-import os
+from functest.utils.constants import CONST
class SnapsSmoke(PyTestSuiteRunner):
@@ -24,18 +26,18 @@ class SnapsSmoke(PyTestSuiteRunner):
self.suite = unittest.TestSuite()
self.case_name = "snaps_smoke"
- creds_file = ft_utils.get_functest_config('general.openstack.creds')
- use_key = ft_utils.get_functest_config('snaps.use_keystone')
- use_fip = ft_utils.get_functest_config('snaps.use_floating_ips')
+ use_fip = CONST.snaps_use_floating_ips
ext_net_name = snaps_utils.get_ext_net_name()
# Tests requiring floating IPs leverage files contained within the
# SNAPS repository and are found relative to that path
if use_fip:
- snaps_dir = ft_utils.get_functest_config(
- 'general.directories.dir_repo_snaps') + '/snaps'
+ snaps_dir = CONST.dir_repo_snaps + '/snaps'
os.chdir(snaps_dir)
test_suite_builder.add_openstack_integration_tests(
- self.suite, creds_file, ext_net_name, use_keystone=use_key,
+ self.suite,
+ CONST.openstack_creds,
+ ext_net_name,
+ use_keystone=CONST.snaps_use_keystone,
use_floating_ips=use_fip)
diff --git a/functest/opnfv_tests/openstack/snaps/snaps_utils.py b/functest/opnfv_tests/openstack/snaps/snaps_utils.py
index a25ad3e0d..4ea1a04ad 100644
--- a/functest/opnfv_tests/openstack/snaps/snaps_utils.py
+++ b/functest/opnfv_tests/openstack/snaps/snaps_utils.py
@@ -5,17 +5,18 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
-import functest.utils.functest_utils as ft_utils
from snaps.openstack.tests import openstack_tests
from snaps.openstack.utils import neutron_utils
+from functest.utils.constants import CONST
+
def get_ext_net_name():
"""
Returns the first external network name
:return:
"""
- os_env_file = ft_utils.get_functest_config('general.openstack.creds')
+ os_env_file = CONST.openstack_creds
os_creds = openstack_tests.get_credentials(os_env_file=os_env_file)
neutron = neutron_utils.neutron_client(os_creds)
ext_nets = neutron_utils.get_external_networks(neutron)
diff --git a/functest/opnfv_tests/openstack/tempest/conf_utils.py b/functest/opnfv_tests/openstack/tempest/conf_utils.py
index 38b97e74e..67b527968 100644
--- a/functest/opnfv_tests/openstack/tempest/conf_utils.py
+++ b/functest/opnfv_tests/openstack/tempest/conf_utils.py
@@ -12,18 +12,20 @@ import os
import re
import shutil
-import functest.utils.functest_constants as ft_constants
-import functest.utils.functest_utils as ft_utils
import opnfv.utils.constants as releng_constants
+from functest.utils.constants import CONST
+import functest.utils.functest_utils as ft_utils
+import functest.utils.openstack_utils as os_utils
+
IMAGE_ID_ALT = None
FLAVOR_ID_ALT = None
-REPO_PATH = ft_constants.FUNCTEST_REPO_DIR
-GLANCE_IMAGE_PATH = os.path.join(ft_constants.FUNCTEST_DATA_DIR,
- ft_constants.GLANCE_IMAGE_FILENAME)
-TEMPEST_TEST_LIST_DIR = ft_constants.TEMPEST_TEST_LIST_DIR
-TEMPEST_RESULTS_DIR = os.path.join(ft_constants.FUNCTEST_RESULTS_DIR,
+REPO_PATH = CONST.dir_repo_functest
+GLANCE_IMAGE_PATH = os.path.join(CONST.dir_functest_data,
+ CONST.openstack_image_file_name)
+TEMPEST_TEST_LIST_DIR = CONST.dir_tempest_cases
+TEMPEST_RESULTS_DIR = os.path.join(CONST.dir_results,
'tempest')
TEMPEST_CUSTOM = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR,
'test_list.txt')
@@ -34,24 +36,25 @@ TEMPEST_DEFCORE = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR,
TEMPEST_RAW_LIST = os.path.join(TEMPEST_RESULTS_DIR, 'test_raw_list.txt')
TEMPEST_LIST = os.path.join(TEMPEST_RESULTS_DIR, 'test_list.txt')
-CI_INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
-CI_INSTALLER_IP = ft_constants.CI_INSTALLER_IP
+CI_INSTALLER_TYPE = CONST.INSTALLER_TYPE
+CI_INSTALLER_IP = CONST.INSTALLER_IP
def configure_tempest(logger, deployment_dir, IMAGE_ID=None, FLAVOR_ID=None):
"""
Add/update needed parameters into tempest.conf file generated by Rally
"""
- tempest_conf_file = deployment_dir + "/tempest.conf"
+ tempest_conf_file = os.path.join(deployment_dir, "tempest.conf")
if os.path.isfile(tempest_conf_file):
- logger.debug("Deleting old tempest.conf file...")
- os.remove(tempest_conf_file)
-
- logger.debug("Generating new tempest.conf file...")
- cmd = "rally verify genconfig"
+ logger.debug("Verifier is already configured.")
+ logger.debug("Reconfiguring the current verifier...")
+ cmd = "rally verify configure-verifier --reconfigure"
+ else:
+ logger.info("Configuring the verifier...")
+ cmd = "rally verify configure-verifier"
ft_utils.execute_command(cmd)
- logger.debug("Finding tempest.conf file...")
+ logger.debug("Looking for tempest.conf file...")
if not os.path.isfile(tempest_conf_file):
logger.error("Tempest configuration file %s NOT found."
% tempest_conf_file)
@@ -63,24 +66,24 @@ def configure_tempest(logger, deployment_dir, IMAGE_ID=None, FLAVOR_ID=None):
config.set(
'compute',
'fixed_network_name',
- ft_constants.TEMPEST_PRIVATE_NET_NAME)
- if ft_constants.TEMPEST_USE_CUSTOM_IMAGES:
+ CONST.tempest_private_net_name)
+ if CONST.tempest_use_custom_images:
if IMAGE_ID is not None:
config.set('compute', 'image_ref', IMAGE_ID)
if IMAGE_ID_ALT is not None:
config.set('compute', 'image_ref_alt', IMAGE_ID_ALT)
- if ft_constants.TEMPEST_USE_CUSTOM_FLAVORS:
+ if CONST.tempest_use_custom_flavors:
if FLAVOR_ID is not None:
config.set('compute', 'flavor_ref', FLAVOR_ID)
if FLAVOR_ID_ALT is not None:
config.set('compute', 'flavor_ref_alt', FLAVOR_ID_ALT)
- config.set('identity', 'tenant_name', ft_constants.TEMPEST_TENANT_NAME)
- config.set('identity', 'username', ft_constants.TEMPEST_USER_NAME)
- config.set('identity', 'password', ft_constants.TEMPEST_USER_PASSWORD)
+ config.set('identity', 'tenant_name', CONST.tempest_identity_tenant_name)
+ config.set('identity', 'username', CONST.tempest_identity_user_name)
+ config.set('identity', 'password', CONST.tempest_identity_user_password)
config.set(
- 'validation', 'ssh_timeout', ft_constants.TEMPEST_SSH_TIMEOUT)
+ 'validation', 'ssh_timeout', CONST.tempest_validation_ssh_timeout)
- if ft_constants.OS_ENDPOINT_TYPE is not None:
+ if CONST.OS_ENDPOINT_TYPE is not None:
services_list = ['compute',
'volume',
'image',
@@ -93,14 +96,14 @@ def configure_tempest(logger, deployment_dir, IMAGE_ID=None, FLAVOR_ID=None):
if service not in sections:
config.add_section(service)
config.set(service, 'endpoint_type',
- ft_constants.OS_ENDPOINT_TYPE)
+ CONST.OS_ENDPOINT_TYPE)
with open(tempest_conf_file, 'wb') as config_file:
config.write(config_file)
# Copy tempest.conf to /home/opnfv/functest/results/tempest/
- shutil.copyfile(
- tempest_conf_file, TEMPEST_RESULTS_DIR + '/tempest.conf')
+ shutil.copyfile(tempest_conf_file,
+ os.path.join(TEMPEST_RESULTS_DIR, 'tempest.conf'))
return releng_constants.EXIT_OK
@@ -113,7 +116,7 @@ def configure_tempest_multisite(logger, deployment_dir):
configure_tempest(logger, deployment_dir)
logger.debug("Finding tempest.conf file...")
- tempest_conf_old = os.path.join(deployment_dir, '/tempest.conf')
+ tempest_conf_old = os.path.join(deployment_dir, 'tempest.conf')
if not os.path.isfile(tempest_conf_old):
logger.error("Tempest configuration file %s NOT found."
% tempest_conf_old)
@@ -121,7 +124,7 @@ def configure_tempest_multisite(logger, deployment_dir):
# Copy tempest.conf to /home/opnfv/functest/results/tempest/
cur_path = os.path.split(os.path.realpath(__file__))[0]
- tempest_conf_file = os.path.join(cur_path, '/tempest_multisite.conf')
+ tempest_conf_file = os.path.join(cur_path, 'tempest_multisite.conf')
shutil.copyfile(tempest_conf_old, tempest_conf_file)
logger.debug("Updating selected tempest.conf parameters...")
@@ -129,21 +132,21 @@ def configure_tempest_multisite(logger, deployment_dir):
config.read(tempest_conf_file)
config.set('service_available', 'kingbird', 'true')
- cmd = ("openstack endpoint show kingbird | grep publicurl |"
- "awk '{print $4}' | awk -F '/' '{print $4}'")
- kingbird_api_version = os.popen(cmd).read()
+ # cmd = ("openstack endpoint show kingbird | grep publicurl |"
+ # "awk '{print $4}' | awk -F '/' '{print $4}'")
+ # kingbird_api_version = os.popen(cmd).read()
+ kingbird_api_version = os_utils.get_endpoint(service_type='kingbird')
+
if CI_INSTALLER_TYPE == 'fuel':
# For MOS based setup, the service is accessible
# via bind host
kingbird_conf_path = "/etc/kingbird/kingbird.conf"
installer_type = CI_INSTALLER_TYPE
installer_ip = CI_INSTALLER_IP
- installer_username = ft_utils.get_functest_config(
- "multisite." + installer_type +
- "_environment.installer_username")
- installer_password = ft_utils.get_functest_config(
- "multisite." + installer_type +
- "_environment.installer_password")
+ installer_username = CONST.__getattribute__(
+ 'multisite_{}_installer_username'.format(installer_type))
+ installer_password = CONST.__getattribute__(
+ 'multisite_{}_installer_password'.format(installer_type))
ssh_options = ("-o UserKnownHostsFile=/dev/null -o "
"StrictHostKeyChecking=no")
@@ -174,9 +177,10 @@ def configure_tempest_multisite(logger, deployment_dir):
bind_details)[0]
kingbird_endpoint_url = "http://%s:%s/" % (bind_host, bind_port)
else:
- cmd = "openstack endpoint show kingbird | grep publicurl |\
- awk '{print $4}' | awk -F '/' '{print $3}'"
- kingbird_endpoint_url = os.popen(cmd).read()
+ # cmd = "openstack endpoint show kingbird | grep publicurl |\
+ # awk '{print $4}' | awk -F '/' '{print $3}'"
+ # kingbird_endpoint_url = os.popen(cmd).read()
+ kingbird_endpoint_url = os_utils.get_endpoint(service_type='kingbird')
try:
config.add_section("kingbird")
diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py
index ec0ca766b..0014b7187 100644
--- a/functest/opnfv_tests/openstack/tempest/tempest.py
+++ b/functest/opnfv_tests/openstack/tempest/tempest.py
@@ -16,13 +16,12 @@ import time
import yaml
-import conf_utils
-import functest.core.testcase_base as testcase_base
+from functest.core import testcase_base
+from functest.opnfv_tests.openstack.tempest import conf_utils
+from functest.utils.constants import CONST
import functest.utils.functest_logger as ft_logger
import functest.utils.functest_utils as ft_utils
import functest.utils.openstack_utils as os_utils
-import functest.utils.functest_constants as ft_constants
-import opnfv.utils.constants as releng_constants
""" logging configuration """
logger = ft_logger.Logger("Tempest").getLogger()
@@ -31,14 +30,80 @@ logger = ft_logger.Logger("Tempest").getLogger()
class TempestCommon(testcase_base.TestcaseBase):
def __init__(self):
- self.case_name = ""
+ super(TempestCommon, self).__init__()
self.MODE = ""
self.OPTION = ""
self.FLAVOR_ID = None
self.IMAGE_ID = None
- self.DEPLOYMENT_DIR = ft_utils.get_deployment_dir()
-
- def read_file(self, filename):
+ self.VERIFIER_ID = self.get_verifier_id()
+ self.VERIFIER_REPO_DIR = self.get_verifier_repo_dir()
+ self.DEPLOYMENT_ID = self.get_verifier_deployment_id()
+ self.DEPLOYMENT_DIR = self.get_verifier_deployment_dir()
+ self.VERIFICATION_ID = None
+
+ @staticmethod
+ def get_verifier_id():
+ """
+ Returns verifer id for current Tempest
+ """
+ cmd = ("rally verify list-verifiers | awk '/" +
+ CONST.tempest_deployment_name +
+ "/ {print $2}'")
+ p = subprocess.Popen(cmd, shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ deployment_uuid = p.stdout.readline().rstrip()
+ if deployment_uuid == "":
+ logger.error("Tempest verifier not found.")
+ raise Exception('Error with command:%s' % cmd)
+ return deployment_uuid
+
+ @staticmethod
+ def get_verifier_deployment_id():
+ """
+ Returns deployment id for active Rally deployment
+ """
+ cmd = ("rally deployment list | awk '/" +
+ CONST.rally_deployment_name +
+ "/ {print $2}'")
+ p = subprocess.Popen(cmd, shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ deployment_uuid = p.stdout.readline().rstrip()
+ if deployment_uuid == "":
+ logger.error("Rally deployment not found.")
+ raise Exception('Error with command:%s' % cmd)
+ return deployment_uuid
+
+ def get_verifier_repo_dir(self):
+ """
+ Returns installed verfier repo directory for Tempest
+ """
+ if not self.VERIFIER_ID:
+ self.VERIFIER_ID = self.get_verifier_id()
+
+ return os.path.join(CONST.dir_rally_inst,
+ 'verification',
+ 'verifier-{}'.format(self.VERIFIER_ID),
+ 'repo')
+
+ def get_verifier_deployment_dir(self):
+ """
+ Returns Rally deployment directory for current verifier
+ """
+ if not self.VERIFIER_ID:
+ self.VERIFIER_ID = self.get_verifier_id()
+
+ if not self.DEPLOYMENT_ID:
+ self.DEPLOYMENT_ID = self.get_verifier_deployment_id()
+
+ return os.path.join(CONST.dir_rally_inst,
+ 'verification',
+ 'verifier-{}'.format(self.VERIFIER_ID),
+ 'for-deployment-{}'.format(self.DEPLOYMENT_ID))
+
+ @staticmethod
+ def read_file(filename):
with open(filename) as src:
return [line.strip() for line in src.readlines()]
@@ -48,53 +113,52 @@ class TempestCommon(testcase_base.TestcaseBase):
logger.debug("Creating tenant and user for Tempest suite")
tenant_id = os_utils.create_tenant(
keystone_client,
- ft_constants.TEMPEST_TENANT_NAME,
- ft_constants.TEMPEST_TENANT_DESCRIPTION)
+ CONST.tempest_identity_tenant_name,
+ CONST.tempest_identity_tenant_description)
if not tenant_id:
logger.error("Error : Failed to create %s tenant"
- % ft_constants.TEMPEST_TENANT_NAME)
+ % CONST.tempest_identity_tenant_name)
user_id = os_utils.create_user(keystone_client,
- ft_constants.TEMPEST_USER_NAME,
- ft_constants.TEMPEST_USER_PASSWORD,
+ CONST.tempest_identity_user_name,
+ CONST.tempest_identity_user_password,
None, tenant_id)
if not user_id:
logger.error("Error : Failed to create %s user" %
- ft_constants.TEMPEST_USER_NAME)
+ CONST.tempest_identity_user_name)
logger.debug("Creating private network for Tempest suite")
- network_dic = \
- os_utils.create_shared_network_full(
- ft_constants.TEMPEST_PRIVATE_NET_NAME,
- ft_constants.TEMPEST_PRIVATE_SUBNET_NAME,
- ft_constants.TEMPEST_ROUTER_NAME,
- ft_constants.TEMPEST_PRIVATE_SUBNET_CIDR)
+ network_dic = os_utils.create_shared_network_full(
+ CONST.tempest_private_net_name,
+ CONST.tempest_private_subnet_name,
+ CONST.tempest_router_name,
+ CONST.tempest_private_subnet_cidr)
if not network_dic:
- return releng_constants.EXIT_RUN_ERROR
+ return testcase_base.TestcaseBase.EX_RUN_ERROR
- if ft_constants.TEMPEST_USE_CUSTOM_IMAGES:
+ if CONST.tempest_use_custom_images:
# adding alternative image should be trivial should we need it
logger.debug("Creating image for Tempest suite")
_, self.IMAGE_ID = os_utils.get_or_create_image(
- ft_constants.GLANCE_IMAGE_NAME, conf_utils.GLANCE_IMAGE_PATH,
- ft_constants.GLANCE_IMAGE_FORMAT)
+ CONST.openstack_image_name, conf_utils.GLANCE_IMAGE_PATH,
+ CONST.openstack_image_disk_format)
if not self.IMAGE_ID:
- return releng_constants.EXIT_RUN_ERROR
+ return testcase_base.TestcaseBase.EX_RUN_ERROR
- if ft_constants.TEMPEST_USE_CUSTOM_FLAVORS:
+ if CONST.tempest_use_custom_flavors:
# adding alternative flavor should be trivial should we need it
logger.debug("Creating flavor for Tempest suite")
_, self.FLAVOR_ID = os_utils.get_or_create_flavor(
- ft_constants.FLAVOR_NAME,
- ft_constants.FLAVOR_RAM,
- ft_constants.FLAVOR_DISK,
- ft_constants.FLAVOR_VCPUS)
+ CONST.openstack_flavor_name,
+ CONST.openstack_flavor_ram,
+ CONST.openstack_flavor_disk,
+ CONST.openstack_flavor_vcpus)
if not self.FLAVOR_ID:
- return releng_constants.EXIT_RUN_ERROR
+ return testcase_base.TestcaseBase.EX_RUN_ERROR
- return releng_constants.EXIT_OK
+ return testcase_base.TestcaseBase.EX_OK
- def generate_test_list(self, DEPLOYMENT_DIR):
+ def generate_test_list(self, verifier_repo_dir):
logger.debug("Generating test case list...")
if self.MODE == 'defcore':
shutil.copyfile(
@@ -106,7 +170,7 @@ class TempestCommon(testcase_base.TestcaseBase):
else:
logger.error("Tempest test list file %s NOT found."
% conf_utils.TEMPEST_CUSTOM)
- return releng_constants.EXIT_RUN_ERROR
+ return testcase_base.TestcaseBase.EX_RUN_ERROR
else:
if self.MODE == 'smoke':
testr_mode = "smoke"
@@ -116,11 +180,14 @@ class TempestCommon(testcase_base.TestcaseBase):
testr_mode = ""
else:
testr_mode = 'tempest.api.' + self.MODE
- cmd = ("cd " + DEPLOYMENT_DIR + ";" + "testr list-tests " +
- testr_mode + ">" + conf_utils.TEMPEST_RAW_LIST + ";cd")
+ cmd = ("cd {0};"
+ "testr list-tests {1} > {2};"
+ "cd -;".format(verifier_repo_dir,
+ testr_mode,
+ conf_utils.TEMPEST_RAW_LIST))
ft_utils.execute_command(cmd)
- return releng_constants.EXIT_OK
+ return testcase_base.TestcaseBase.EX_OK
def apply_tempest_blacklist(self):
logger.debug("Applying tempest blacklist...")
@@ -128,8 +195,8 @@ class TempestCommon(testcase_base.TestcaseBase):
result_file = open(conf_utils.TEMPEST_LIST, 'w')
black_tests = []
try:
- installer_type = ft_constants.CI_INSTALLER_TYPE
- deploy_scenario = ft_constants.CI_SCENARIO
+ installer_type = CONST.INSTALLER_TYPE
+ deploy_scenario = CONST.DEPLOY_SCENARIO
if (bool(installer_type) * bool(deploy_scenario)):
# if INSTALLER_TYPE and DEPLOY_SCENARIO are set we read the
# file
@@ -145,7 +212,7 @@ class TempestCommon(testcase_base.TestcaseBase):
for test in tests:
black_tests.append(test)
break
- except:
+ except Exception:
black_tests = []
logger.debug("Tempest blacklist file does not exist.")
@@ -156,52 +223,35 @@ class TempestCommon(testcase_base.TestcaseBase):
else:
result_file.write(str(cases_line) + '\n')
result_file.close()
- return releng_constants.EXIT_OK
+ return testcase_base.TestcaseBase.EX_OK
- def run(self):
- if not os.path.exists(conf_utils.TEMPEST_RESULTS_DIR):
- os.makedirs(conf_utils.TEMPEST_RESULTS_DIR)
+ def _parse_verification_id(line):
+ first_pos = line.index("UUID=") + len("UUID=")
+ last_pos = line.index(") for deployment")
+ return line[first_pos:last_pos]
- # Pre-configuration
- res = self.create_tempest_resources()
- if res != releng_constants.EXIT_OK:
- return res
+ def run_verifier_tests(self):
+ self.OPTION += (" --load-list {}".format(conf_utils.TEMPEST_LIST))
- res = conf_utils.configure_tempest(logger,
- self.DEPLOYMENT_DIR,
- self.IMAGE_ID,
- self.FLAVOR_ID)
- if res != releng_constants.EXIT_OK:
- return res
-
- res = self.generate_test_list(self.DEPLOYMENT_DIR)
- if res != releng_constants.EXIT_OK:
- return res
-
- res = self.apply_tempest_blacklist()
- if res != releng_constants.EXIT_OK:
- return res
-
- self.OPTION += (" --tests-file %s " % conf_utils.TEMPEST_LIST)
-
- cmd_line = "rally verify start " + self.OPTION + " --system-wide"
+ cmd_line = "rally verify start " + self.OPTION
logger.info("Starting Tempest test suite: '%s'." % cmd_line)
header = ("Tempest environment:\n"
" Installer: %s\n Scenario: %s\n Node: %s\n Date: %s\n" %
- (ft_constants.CI_INSTALLER_TYPE,
- ft_constants.CI_SCENARIO,
- ft_constants.CI_NODE,
+ (CONST.INSTALLER_TYPE,
+ CONST.DEPLOY_SCENARIO,
+ CONST.NODE_NAME,
time.strftime("%a %b %d %H:%M:%S %Z %Y")))
- f_stdout = open(conf_utils.TEMPEST_RESULTS_DIR + "/tempest.log", 'w+')
+ f_stdout = open(
+ os.path.join(conf_utils.TEMPEST_RESULTS_DIR, "tempest.log"), 'w+')
f_stderr = open(
- conf_utils.TEMPEST_RESULTS_DIR + "/tempest-error.log", 'w+')
- f_env = open(conf_utils.TEMPEST_RESULTS_DIR + "/environment.log", 'w+')
+ os.path.join(conf_utils.TEMPEST_RESULTS_DIR,
+ "tempest-error.log"), 'w+')
+ f_env = open(os.path.join(conf_utils.TEMPEST_RESULTS_DIR,
+ "environment.log"), 'w+')
f_env.write(header)
- # subprocess.call(cmd_line, shell=True,
- # stdout=f_stdout, stderr=f_stderr)
p = subprocess.Popen(
cmd_line, shell=True,
stdout=subprocess.PIPE,
@@ -212,6 +262,12 @@ class TempestCommon(testcase_base.TestcaseBase):
for line in iter(p.stdout.readline, b''):
if re.search("\} tempest\.", line):
logger.info(line.replace('\n', ''))
+ elif re.search('Starting verification', line):
+ logger.info(line.replace('\n', ''))
+ first_pos = line.index("UUID=") + len("UUID=")
+ last_pos = line.index(") for deployment")
+ self.VERIFICATION_ID = line[first_pos:last_pos]
+ logger.debug('Verication UUID: %s' % self.VERIFICATION_ID)
f_stdout.write(line)
p.wait()
@@ -219,56 +275,76 @@ class TempestCommon(testcase_base.TestcaseBase):
f_stderr.close()
f_env.close()
- cmd_line = "rally verify show"
- output = ""
+ def parse_verifier_result(self):
+ if not self.VERIFICATION_ID:
+ raise Exception('Verification UUID not found')
+
+ cmd_line = "rally verify show --uuid {}".format(self.VERIFICATION_ID)
+ logger.info("Showing result for a verification: '%s'." % cmd_line)
p = subprocess.Popen(cmd_line,
shell=True,
stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ stderr=subprocess.STDOUT)
for line in p.stdout:
- if re.search("Tests\:", line):
+ new_line = line.replace(' ', '').split('|')
+ if 'Tests' in new_line:
break
- output += line
- logger.info(output)
-
- cmd_line = "rally verify list"
- cmd = os.popen(cmd_line)
- output = (((cmd.read()).splitlines()[-2]).replace(" ", "")).split("|")
- # Format:
- # | UUID | Deployment UUID | smoke | tests | failures | Created at |
- # Duration | Status |
- num_tests = output[4]
- num_failures = output[5]
- duration = output[7]
- # Compute duration (lets assume it does not take more than 60 min)
- dur_min = int(duration.split(':')[1])
- dur_sec_float = float(duration.split(':')[2])
- dur_sec_int = int(round(dur_sec_float, 0))
- dur_sec_int = dur_sec_int + 60 * dur_min
+
+ logger.info(line)
+ if 'Testscount' in new_line:
+ num_tests = new_line[2]
+ elif 'Success' in new_line:
+ num_success = new_line[2]
+ elif 'Skipped' in new_line:
+ num_skipped = new_line[2]
try:
- diff = (int(num_tests) - int(num_failures))
- success_rate = 100 * diff / int(num_tests)
- except:
+ num_executed = int(num_tests) - int(num_skipped)
+ success_rate = 100 * int(num_success) / int(num_executed)
+ except Exception:
success_rate = 0
- if 'smoke' in self.MODE:
- self.CASE_NAME = 'tempest_smoke_serial'
- elif 'feature' in self.MODE:
- self.CASE_NAME = self.MODE.replace(
- "feature_", "")
- else:
- self.CASE_NAME = 'tempest_full_parallel'
-
- status = ft_utils.check_success_rate(
- self.CASE_NAME, success_rate)
+ self.criteria = ft_utils.check_success_rate(
+ self.case_name, success_rate)
logger.info("Tempest %s success_rate is %s%%, is marked as %s"
- % (self.CASE_NAME, success_rate, status))
+ % (self.case_name, success_rate, self.criteria))
+
+ def run(self):
+
+ self.start_time = time.time()
+
+ if not os.path.exists(conf_utils.TEMPEST_RESULTS_DIR):
+ os.makedirs(conf_utils.TEMPEST_RESULTS_DIR)
+
+ # Pre-configuration
+ res = self.create_tempest_resources()
+ if res != testcase_base.TestcaseBase.EX_OK:
+ return res
+
+ res = conf_utils.configure_tempest(logger,
+ self.DEPLOYMENT_DIR,
+ self.IMAGE_ID,
+ self.FLAVOR_ID)
+ if res != testcase_base.TestcaseBase.EX_OK:
+ return res
+
+ res = self.generate_test_list(self.VERIFIER_REPO_DIR)
+ if res != testcase_base.TestcaseBase.EX_OK:
+ return res
+
+ res = self.apply_tempest_blacklist()
+ if res != testcase_base.TestcaseBase.EX_OK:
+ return res
+
+ self.run_verifier_tests()
+ self.parse_verifier_result()
+
+ self.stop_time = time.time()
- if status == "PASS":
- return releng_constants.EXIT_OK
+ if self.criteria == "PASS":
+ return testcase_base.TestcaseBase.EX_OK
else:
- return releng_constants.EXIT_RUN_ERROR
+ return testcase_base.TestcaseBase.EX_TESTCASE_FAILED
class TempestSmokeSerial(TempestCommon):
@@ -277,7 +353,7 @@ class TempestSmokeSerial(TempestCommon):
TempestCommon.__init__(self)
self.case_name = "tempest_smoke_serial"
self.MODE = "smoke"
- self.OPTION = "--concur 1"
+ self.OPTION = "--concurrency 1"
class TempestSmokeParallel(TempestCommon):
@@ -303,7 +379,7 @@ class TempestMultisite(TempestCommon):
TempestCommon.__init__(self)
self.case_name = "multisite"
self.MODE = "feature_multisite"
- self.OPTION = "--concur 1"
+ self.OPTION = "--concurrency 1"
conf_utils.configure_tempest_multisite(logger, self.DEPLOYMENT_DIR)
diff --git a/functest/opnfv_tests/openstack/vping/vping_base.py b/functest/opnfv_tests/openstack/vping/vping_base.py
index e467dd9f5..8285d93f8 100644
--- a/functest/opnfv_tests/openstack/vping/vping_base.py
+++ b/functest/opnfv_tests/openstack/vping/vping_base.py
@@ -12,43 +12,38 @@ import pprint
import time
from datetime import datetime
-import functest.utils.functest_utils as ft_utils
-import functest.utils.functest_constants as ft_constants
-import functest.utils.openstack_utils as os_utils
import functest.core.testcase_base as testcase_base
+import functest.utils.openstack_utils as os_utils
+from functest.utils.constants import CONST
class VPingBase(testcase_base.TestcaseBase):
def __init__(self):
- def get_conf(parameter):
- return ft_utils.get_functest_config(parameter)
-
super(VPingBase, self).__init__()
self.logger = None
- self.functest_repo = ft_constants.FUNCTEST_REPO_DIR
- self.repo = get_conf('general.directories.dir_vping')
- self.vm1_name = get_conf('vping.vm_name_1')
- self.vm2_name = get_conf('vping.vm_name_2')
+ self.functest_repo = CONST.dir_repo_functest
+ self.repo = CONST.dir_vping
+ self.vm1_name = CONST.vping_vm_name_1
+ self.vm2_name = CONST.vping_vm_name_2
self.vm_boot_timeout = 180
self.vm_delete_timeout = 100
- self.ping_timeout = get_conf('vping.ping_timeout')
+ self.ping_timeout = CONST.vping_ping_timeout
- self.image_name = get_conf('vping.image_name')
- self.image_filename = get_conf('general.openstack.image_file_name')
- self.image_format = get_conf('general.openstack.image_disk_format')
- self.image_path = ("%s/%s" %
- (get_conf('general.directories.dir_functest_data'),
- self.image_filename))
+ self.image_name = CONST.vping_image_name
+ self.image_filename = CONST.openstack_image_file_name
+ self.image_format = CONST.openstack_image_disk_format
+ self.image_path = os.path.join(CONST.dir_functest_data,
+ self.image_filename)
- self.flavor_name = get_conf('vping.vm_flavor')
+ self.flavor_name = CONST.vping_vm_flavor
# NEUTRON Private Network parameters
- self.private_net_name = get_conf('vping.vping_private_net_name')
- self.private_subnet_name = get_conf('vping.vping_private_subnet_name')
- self.private_subnet_cidr = get_conf('vping.vping_private_subnet_cidr')
- self.router_name = get_conf('vping.vping_router_name')
- self.sg_name = get_conf('vping.vping_sg_name')
- self.sg_desc = get_conf('vping.vping_sg_descr')
+ self.private_net_name = CONST.vping_private_net_name
+ self.private_subnet_name = CONST.vping_private_subnet_name
+ self.private_subnet_cidr = CONST.vping_private_subnet_cidr
+ self.router_name = CONST.vping_router_name
+ self.sg_name = CONST.vping_sg_name
+ self.sg_desc = CONST.vping_sg_desc
self.neutron_client = os_utils.get_neutron_client()
self.glance_client = os_utils.get_glance_client()
self.nova_client = os_utils.get_nova_client()
@@ -294,6 +289,6 @@ class VPingMain(object):
if result != VPingBase.EX_OK:
return result
if kwargs['report']:
- return self.vping.push_to_db()
+ return self.vping.publish_report()
except Exception:
return VPingBase.EX_RUN_ERROR
diff --git a/functest/opnfv_tests/sdn/odl/odl.py b/functest/opnfv_tests/sdn/odl/odl.py
index 0905e55cc..339c305ef 100755
--- a/functest/opnfv_tests/sdn/odl/odl.py
+++ b/functest/opnfv_tests/sdn/odl/odl.py
@@ -15,7 +15,7 @@ import re
import sys
import urlparse
-from robot.api import ExecutionResult, ResultVisitor
+import robot.api
from robot.errors import RobotError
import robot.run
from robot.utils.robottime import timestamp_to_secs
@@ -25,7 +25,7 @@ import functest.utils.functest_logger as ft_logger
import functest.utils.openstack_utils as op_utils
-class ODLResultVisitor(ResultVisitor):
+class ODLResultVisitor(robot.api.ResultVisitor):
def __init__(self):
self._data = []
@@ -79,7 +79,7 @@ class ODLTests(testcase_base.TestcaseBase):
def parse_results(self):
xml_file = os.path.join(self.res_dir, 'output.xml')
- result = ExecutionResult(xml_file)
+ result = robot.api.ExecutionResult(xml_file)
visitor = ODLResultVisitor()
result.visit(visitor)
self.criteria = result.suite.status
@@ -161,7 +161,8 @@ class ODLTests(testcase_base.TestcaseBase):
kwargs['odlwebport'] = '8282'
elif installer_type == 'apex':
kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
- kwargs['odlwebport'] = '8181'
+ kwargs['odlwebport'] = '8081'
+ kwargs['odlrestconfport'] = '8081'
elif installer_type == 'joid':
kwargs['odlip'] = os.environ['SDN_CONTROLLER']
elif installer_type == 'compass':
@@ -180,49 +181,57 @@ class ODLTests(testcase_base.TestcaseBase):
return self.main(**kwargs)
+class ODLParser():
+
+ def __init__(self):
+ self.parser = argparse.ArgumentParser()
+ self.parser.add_argument(
+ '-k', '--keystoneip', help='Keystone IP',
+ default='127.0.0.1')
+ self.parser.add_argument(
+ '-n', '--neutronip', help='Neutron IP',
+ default='127.0.0.1')
+ self.parser.add_argument(
+ '-a', '--osusername', help='Username for OpenStack',
+ default='admin')
+ self.parser.add_argument(
+ '-b', '--ostenantname', help='Tenantname for OpenStack',
+ default='admin')
+ self.parser.add_argument(
+ '-c', '--ospassword', help='Password for OpenStack',
+ default='admin')
+ self.parser.add_argument(
+ '-o', '--odlip', help='OpenDaylight IP',
+ default='127.0.0.1')
+ self.parser.add_argument(
+ '-w', '--odlwebport', help='OpenDaylight Web Portal Port',
+ default='8080')
+ self.parser.add_argument(
+ '-r', '--odlrestconfport', help='OpenDaylight RESTConf Port',
+ default='8181')
+ self.parser.add_argument(
+ '-d', '--odlusername', help='Username for ODL',
+ default='admin')
+ self.parser.add_argument(
+ '-e', '--odlpassword', help='Password for ODL',
+ default='admin')
+ self.parser.add_argument(
+ '-p', '--pushtodb', help='Push results to DB',
+ action='store_true')
+
+ def parse_args(self, argv=[]):
+ return vars(self.parser.parse_args(argv))
+
+
if __name__ == '__main__':
- parser = argparse.ArgumentParser()
- parser.add_argument('-k', '--keystoneip',
- help='Keystone IP',
- default='127.0.0.1')
- parser.add_argument('-n', '--neutronip',
- help='Neutron IP',
- default='127.0.0.1')
- parser.add_argument('-a', '--osusername',
- help='Username for OpenStack',
- default='admin')
- parser.add_argument('-b', '--ostenantname',
- help='Tenantname for OpenStack',
- default='admin')
- parser.add_argument('-c', '--ospassword',
- help='Password for OpenStack',
- default='admin')
- parser.add_argument('-o', '--odlip',
- help='OpenDaylight IP',
- default='127.0.0.1')
- parser.add_argument('-w', '--odlwebport',
- help='OpenDaylight Web Portal Port',
- default='8080')
- parser.add_argument('-r', '--odlrestconfport',
- help='OpenDaylight RESTConf Port',
- default='8181')
- parser.add_argument('-d', '--odlusername',
- help='Username for ODL',
- default='admin')
- parser.add_argument('-e', '--odlpassword',
- help='Password for ODL',
- default='admin')
- parser.add_argument('-p', '--pushtodb',
- help='Push results to DB',
- action='store_true')
-
- args = vars(parser.parse_args())
odl = ODLTests()
+ parser = ODLParser()
+ args = parser.parse_args(sys.argv[1:])
try:
result = odl.main(**args)
if result != testcase_base.TestcaseBase.EX_OK:
sys.exit(result)
if args['pushtodb']:
- sys.exit(odl.push_to_db())
+ sys.exit(odl.publish_report())
except Exception:
sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)
diff --git a/functest/opnfv_tests/sdn/onos/teston/onos.py b/functest/opnfv_tests/sdn/onos/teston/onos.py
index 300f56d18..213bdb7dc 100755
--- a/functest/opnfv_tests/sdn/onos/teston/onos.py
+++ b/functest/opnfv_tests/sdn/onos/teston/onos.py
@@ -18,14 +18,15 @@ import datetime
import os
import re
import time
+import urlparse
import argparse
from neutronclient.v2_0 import client as neutronclient
+import functest.utils.functest_constants as ft_constants
import functest.utils.functest_logger as ft_logger
import functest.utils.functest_utils as ft_utils
import functest.utils.openstack_utils as openstack_utils
-import functest.utils.functest_constants as ft_constants
parser = argparse.ArgumentParser()
@@ -135,9 +136,9 @@ def GetResult():
def SetOnosIp():
- cmd = "openstack catalog show network | grep publicURL"
- cmd_output = os.popen(cmd).read()
- OC1 = re.search(r"\d+\.\d+\.\d+\.\d+", cmd_output).group()
+ # cmd = "openstack catalog show network | grep publicURL"
+ neutron_url = openstack_utils.get_endpoint(service_type='network')
+ OC1 = urlparse.urlparse(neutron_url).hostname
os.environ['OC1'] = OC1
time.sleep(2)
logger.debug("ONOS IP is " + OC1)
@@ -180,10 +181,9 @@ def SfcTest():
def GetIp(type):
- cmd = "openstack catalog show " + type + " | grep publicURL"
- cmd_output = os.popen(cmd).read()
- ip = re.search(r"\d+\.\d+\.\d+\.\d+", cmd_output).group()
- return ip
+ # cmd = "openstack catalog show " + type + " | grep publicURL"
+ url = openstack_utils.get_endpoint(service_type=type)
+ return urlparse.urlparse(url).hostname
def Replace(before, after):
diff --git a/functest/opnfv_tests/vnf/aaa/__init__.py b/functest/opnfv_tests/vnf/aaa/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/opnfv_tests/vnf/aaa/__init__.py
diff --git a/functest/opnfv_tests/vnf/aaa/aaa.py b/functest/opnfv_tests/vnf/aaa/aaa.py
new file mode 100644
index 000000000..f1c265f47
--- /dev/null
+++ b/functest/opnfv_tests/vnf/aaa/aaa.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2016 Orange 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
+
+import sys
+
+import argparse
+
+import functest.core.testcase_base as testcase_base
+import functest.core.vnf_base as vnf_base
+import functest.utils.functest_logger as ft_logger
+
+
+class AaaVnf(vnf_base.VnfOnBoardingBase):
+
+ logger = ft_logger.Logger("VNF AAA").getLogger()
+
+ def __init__(self):
+ super(AaaVnf, self).__init__(case="aaa")
+
+ def deploy_orchestrator(self):
+ self.logger.info("No VNFM needed to deploy a free radius here")
+ return None
+
+# TODO see how to use build in exception form releng module
+ def deploy_vnf(self):
+ self.logger.info("Freeradius VNF deployment")
+ # TODO apt-get update + config tuning
+ deploy_vnf = {}
+ deploy_vnf['status'] = "PASS"
+ deploy_vnf['result'] = {}
+ return deploy_vnf
+
+ def test_vnf(self):
+ self.logger.info("Run test towards freeradius")
+ # TODO: once the freeradius is deployed..make some tests
+ test_vnf = {}
+ test_vnf['status'] = "PASS"
+ test_vnf['result'] = {}
+ return test_vnf
+
+ def main(self, **kwargs):
+ self.logger.info("AAA VNF onboarding")
+ self.execute()
+ if self.criteria is "PASS":
+ return self.EX_OK
+ else:
+ return self.EX_RUN_ERROR
+
+ def run(self):
+ kwargs = {}
+ return self.main(**kwargs)
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ args = vars(parser.parse_args())
+ aaa_vnf = AaaVnf()
+ try:
+ result = aaa_vnf.main(**args)
+ if result != testcase_base.TestcaseBase.EX_OK:
+ sys.exit(result)
+ if args['pushtodb']:
+ sys.exit(aaa_vnf.push_to_db())
+ except Exception:
+ sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)
diff --git a/functest/opnfv_tests/vnf/ims/__init__.py b/functest/opnfv_tests/vnf/ims/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/opnfv_tests/vnf/ims/__init__.py
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
new file mode 100644
index 000000000..13a5af4fd
--- /dev/null
+++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
@@ -0,0 +1,278 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2016 Orange 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
+
+import json
+import os
+import requests
+import subprocess
+import time
+
+import functest.core.vnf_base as vnf_base
+import functest.utils.functest_logger as ft_logger
+import functest.utils.functest_utils as ft_utils
+import functest.utils.openstack_utils as os_utils
+
+from clearwater import Clearwater
+from functest.utils.constants import CONST
+from orchestrator_cloudify import Orchestrator
+
+
+class ImsVnf(vnf_base.VnfOnBoardingBase):
+
+ def __init__(self, project='functest', case='cloudify_ims',
+ repo='', cmd=''):
+ super(ImsVnf, self).__init__(project, case, repo, cmd)
+ self.logger = ft_logger.Logger("vIMS").getLogger()
+ self.case_dir = os.path.join(CONST.functest_test, 'vnf/ims/')
+ self.data_dir = CONST.dir_vIMS_data
+ self.test_dir = CONST.dir_repo_vims_test
+
+ self.orchestrator = dict(
+ requirements=CONST.cloudify_requirements,
+ blueprint=CONST.cloudify_blueprint,
+ inputs=CONST.cloudify_inputs
+ )
+
+ self.vnf = dict(
+ blueprint=CONST.clearwater_blueprint,
+ deployment_name=CONST.clearwater_deployment_name,
+ inputs=CONST.clearwater_inputs,
+ requirements=CONST.clearwater_requirements
+ )
+
+ # vIMS Data directory creation
+ if not os.path.exists(self.data_dir):
+ os.makedirs(self.data_dir)
+
+ def deploy_orchestrator(self, **kwargs):
+ public_auth_url = os_utils.get_endpoint('identity')
+
+ cfy = Orchestrator(self.data_dir, self.orchestrator.inputs)
+ self.orchestrator.object = cfy
+
+ if 'tenant_name' in self.creds.keys():
+ tenant_name = self.creds['tenant_name']
+ elif 'project_name' in self.creds.keys():
+ tenant_name = self.creds['project_name']
+
+ cfy.set_credentials(username=self.creds['username'],
+ password=self.creds['password'],
+ tenant_name=tenant_name,
+ auth_url=public_auth_url)
+
+ # orchestrator VM flavor
+ flavor_id = self.get_flavor("m1.large", self.orchestrator.requirements)
+ if not flavor_id:
+ self.logger.info("Available flavors are: ")
+ self.pMsg(self.nova_client.flavor.list())
+ self.step_failure("Failed to find required flavor"
+ "for this deployment")
+ cfy.set_flavor_id(flavor_id)
+
+ # orchestrator VM image
+ if 'os_image' in self.orchestrator.requirements.keys():
+ image_id = os_utils.get_image_id(
+ self.glance_client, self.orchestrator.requirements['os_image'])
+ if image_id == '':
+ self.step_failure("Failed to find required OS image"
+ " for cloudify manager")
+ else:
+ self.step_failure("Failed to find required OS image"
+ " for cloudify manager")
+
+ cfy.set_image_id(image_id)
+
+ ext_net = os_utils.get_external_net(self.neutron_client)
+ if not ext_net:
+ self.step_failure("Failed to get external network")
+
+ cfy.set_external_network_name(ext_net)
+
+ ns = ft_utils.get_resolvconf_ns()
+ if ns:
+ cfy.set_nameservers(ns)
+
+ if 'compute' in self.nova_client.client.services_url:
+ cfy.set_nova_url(self.nova_client.client.services_url['compute'])
+ if self.neutron_client.httpclient.endpoint_url is not None:
+ cfy.set_neutron_url(self.neutron_client.httpclient.endpoint_url)
+
+ self.logger.info("Prepare virtualenv for cloudify-cli")
+ cmd = "chmod +x " + self.case_dir + "create_venv.sh"
+ ft_utils.execute_command(cmd)
+ time.sleep(3)
+ cmd = self.case_dir + "create_venv.sh " + self.data_dir
+ ft_utils.execute_command(cmd)
+
+ cfy.download_manager_blueprint(self.orchestrator.blueprint['url'],
+ self.orchestrator.blueprint['branch'])
+
+ cfy.deploy_manager()
+ return {'status': 'PASS', 'result': ''}
+
+ def deploy_vnf(self):
+ cw = Clearwater(self.vnf.inputs, self.orchestrator.object, self.logger)
+ self.vnf.object = cw
+
+ self.logger.info("Collect flavor id for all clearwater vm")
+ flavor_id = self.get_flavor("m1.small", self.vnf.requirements)
+ if not flavor_id:
+ self.logger.info("Available flavors are: ")
+ self.pMsg(self.nova_client.flavor.list())
+ self.step_failure("Failed to find required flavor"
+ " for this deployment")
+
+ cw.set_flavor_id(flavor_id)
+
+ # VMs image
+ if 'os_image' in self.vnf.requirements.keys():
+ image_id = os_utils.get_image_id(
+ self.glance_client, self.vnf.requirements['os_image'])
+ if image_id == '':
+ self.step_failure("Failed to find required OS image"
+ " for clearwater VMs")
+ else:
+ self.step_failure("Failed to find required OS image"
+ " for clearwater VMs")
+
+ cw.set_image_id(image_id)
+
+ ext_net = os_utils.get_external_net(self.neutron_client)
+ if not ext_net:
+ self.step_failure("Failed to get external network")
+
+ cw.set_external_network_name(ext_net)
+
+ cw.deploy_vnf()
+ return {'status': 'PASS', 'result': ''}
+
+ def test_vnf(self):
+ script = "source {0}venv_cloudify/bin/activate; "
+ script += "cd {0}; "
+ script += "cfy status | grep -Eo \"([0-9]{{1,3}}\.){{3}}[0-9]{{1,3}}\""
+ cmd = "/bin/bash -c '" + script.format(self.data_dir) + "'"
+
+ try:
+ self.logger.debug("Trying to get clearwater manager IP ... ")
+ mgr_ip = os.popen(cmd).read()
+ mgr_ip = mgr_ip.splitlines()[0]
+ except:
+ self.step_failure("Unable to retrieve the IP of the "
+ "cloudify manager server !")
+
+ api_url = "http://" + mgr_ip + "/api/v2"
+ dep_outputs = requests.get(api_url + "/deployments/" +
+ self.vnf.deployment_name + "/outputs")
+ dns_ip = dep_outputs.json()['outputs']['dns_ip']
+ ellis_ip = dep_outputs.json()['outputs']['ellis_ip']
+
+ ellis_url = "http://" + ellis_ip + "/"
+ url = ellis_url + "accounts"
+
+ params = {"password": "functest",
+ "full_name": "opnfv functest user",
+ "email": "functest@opnfv.fr",
+ "signup_code": "secret"}
+
+ rq = requests.post(url, data=params)
+ i = 20
+ while rq.status_code != 201 and i > 0:
+ rq = requests.post(url, data=params)
+ i = i - 1
+ time.sleep(10)
+
+ if rq.status_code == 201:
+ url = ellis_url + "session"
+ rq = requests.post(url, data=params)
+ cookies = rq.cookies
+
+ url = ellis_url + "accounts/" + params['email'] + "/numbers"
+ if cookies != "":
+ rq = requests.post(url, cookies=cookies)
+ i = 24
+ while rq.status_code != 200 and i > 0:
+ rq = requests.post(url, cookies=cookies)
+ i = i - 1
+ time.sleep(25)
+
+ if rq.status_code != 200:
+ self.step_failure("Unable to create a number: %s"
+ % rq.json()['reason'])
+
+ nameservers = ft_utils.get_resolvconf_ns()
+ resolvconf = ""
+ for ns in nameservers:
+ resolvconf += "\nnameserver " + ns
+
+ if dns_ip != "":
+ script = ('echo -e "nameserver ' + dns_ip + resolvconf +
+ '" > /etc/resolv.conf; ')
+ script += 'source /etc/profile.d/rvm.sh; '
+ script += 'cd {0}; '
+ script += ('rake test[{1}] SIGNUP_CODE="secret"')
+
+ cmd = ("/bin/bash -c '" +
+ script.format(self.data_dir, self.inputs["public_domain"]) +
+ "'")
+ output_file = "output.txt"
+ f = open(output_file, 'w+')
+ subprocess.call(cmd, shell=True, stdout=f,
+ stderr=subprocess.STDOUT)
+ f.close()
+
+ f = open(output_file, 'r')
+ result = f.read()
+ if result != "":
+ self.logger.debug(result)
+
+ vims_test_result = ""
+ tempFile = os.path.join(self.test_dir, "temp.json")
+ try:
+ self.logger.debug("Trying to load test results")
+ with open(tempFile) as f:
+ vims_test_result = json.load(f)
+ f.close()
+ except:
+ self.logger.error("Unable to retrieve test results")
+
+ try:
+ os.remove(tempFile)
+ except:
+ self.logger.error("Deleting file failed")
+
+ if vims_test_result != '':
+ return {'status': 'PASS', 'result': vims_test_result}
+ else:
+ return {'status': 'FAIL', 'result': ''}
+
+ def clean(self):
+ self.vnf.object.undeploy_vnf()
+ self.orchestrator.object.undeploy_manager()
+ super(ImsVnf, self).clean()
+
+ def get_flavor(self, flavor_name, requirements):
+ try:
+ flavor_id = os_utils.get_flavor_id(self.nova_client, flavor_name)
+ if 'ram_min' in requirements.keys():
+ flavor_id = os_utils.get_flavor_id_by_ram_range(
+ self.nova_client, requirements['ram_min'], 7500)
+
+ if flavor_id == '':
+ self.logger.error(
+ "Failed to find %s flavor. "
+ "Try with ram range default requirement !" % flavor_name)
+ flavor_id = os_utils.get_flavor_id_by_ram_range(
+ self.nova_client,
+ 4000, 10000)
+ return flavor_id
+ except:
+ self.logger.error("Flavor '%s' not found." % self.flavor_name)
+ self.logger.info("Available flavors are: ")
+ self.pMsg(self.nova_client.flavor.list())
+ return None
diff --git a/functest/opnfv_tests/vnf/ims/opera_ims.py b/functest/opnfv_tests/vnf/ims/opera_ims.py
new file mode 100644
index 000000000..073a56c37
--- /dev/null
+++ b/functest/opnfv_tests/vnf/ims/opera_ims.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2016 Orange 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
+
+import json
+import os
+import requests
+import subprocess
+import time
+
+import functest.core.vnf_base as vnf_base
+import functest.utils.functest_logger as ft_logger
+import functest.utils.functest_utils as ft_utils
+from functest.utils.constants import CONST
+
+
+class ImsVnf(vnf_base.VnfOnBoardingBase):
+
+ def __init__(self, project='functest', case='opera_ims',
+ repo='', cmd=''):
+ super(ImsVnf, self).__init__(project, case, repo, cmd)
+ self.logger = ft_logger.Logger("vIMS").getLogger()
+ self.case_dir = os.path.join(CONST.functest_test, 'vnf/ims/')
+ self.data_dir = CONST.dir_vIMS_data
+ self.test_dir = CONST.dir_repo_vims_test
+
+ # vIMS Data directory creation
+ if not os.path.exists(self.data_dir):
+ os.makedirs(self.data_dir)
+
+ def deploy_orchestrator(self, **kwargs):
+ # TODO
+ # deploy open-O from Functest docker located on the Jumphost
+ # you have admin rights on OpenStack SUT
+ # you can cretae a VM, spawn docker on the jumphost
+ # spawn docker on a VM in the SUT, ..up to you
+ #
+ # note: this step can be ignored
+ # if Open-O is part of the installer
+ self.logger.info("Deploy orchestrator: OK")
+
+ def deploy_vnf(self):
+ # TODO
+ self.logger.info("Deploy VNF: OK")
+
+ def test_vnf(self):
+ # Adaptations probably needed
+ # code used for cloudify_ims
+ # ruby client on jumphost calling the vIMS on the SUT
+ script = "source {0}venv_cloudify/bin/activate; "
+ script += "cd {0}; "
+ script += "cfy status | grep -Eo \"([0-9]{{1,3}}\.){{3}}[0-9]{{1,3}}\""
+ cmd = "/bin/bash -c '" + script.format(self.data_dir) + "'"
+
+ try:
+ self.logger.debug("Trying to get clearwater manager IP ... ")
+ mgr_ip = os.popen(cmd).read()
+ mgr_ip = mgr_ip.splitlines()[0]
+ except:
+ self.step_failure("Unable to retrieve the IP of the "
+ "cloudify manager server !")
+
+ api_url = "http://" + mgr_ip + "/api/v2"
+ dep_outputs = requests.get(api_url + "/deployments/" +
+ self.vnf.deployment_name + "/outputs")
+ dns_ip = dep_outputs.json()['outputs']['dns_ip']
+ ellis_ip = dep_outputs.json()['outputs']['ellis_ip']
+
+ ellis_url = "http://" + ellis_ip + "/"
+ url = ellis_url + "accounts"
+
+ params = {"password": "functest",
+ "full_name": "opnfv functest user",
+ "email": "functest@opnfv.fr",
+ "signup_code": "secret"}
+
+ rq = requests.post(url, data=params)
+ i = 20
+ while rq.status_code != 201 and i > 0:
+ rq = requests.post(url, data=params)
+ i = i - 1
+ time.sleep(10)
+
+ if rq.status_code == 201:
+ url = ellis_url + "session"
+ rq = requests.post(url, data=params)
+ cookies = rq.cookies
+
+ url = ellis_url + "accounts/" + params['email'] + "/numbers"
+ if cookies != "":
+ rq = requests.post(url, cookies=cookies)
+ i = 24
+ while rq.status_code != 200 and i > 0:
+ rq = requests.post(url, cookies=cookies)
+ i = i - 1
+ time.sleep(25)
+
+ if rq.status_code != 200:
+ self.step_failure("Unable to create a number: %s"
+ % rq.json()['reason'])
+
+ nameservers = ft_utils.get_resolvconf_ns()
+ resolvconf = ""
+ for ns in nameservers:
+ resolvconf += "\nnameserver " + ns
+
+ if dns_ip != "":
+ script = ('echo -e "nameserver ' + dns_ip + resolvconf +
+ '" > /etc/resolv.conf; ')
+ script += 'source /etc/profile.d/rvm.sh; '
+ script += 'cd {0}; '
+ script += ('rake test[{1}] SIGNUP_CODE="secret"')
+
+ cmd = ("/bin/bash -c '" +
+ script.format(self.data_dir, self.inputs["public_domain"]) +
+ "'")
+ output_file = "output.txt"
+ f = open(output_file, 'w+')
+ subprocess.call(cmd, shell=True, stdout=f,
+ stderr=subprocess.STDOUT)
+ f.close()
+
+ f = open(output_file, 'r')
+ result = f.read()
+ if result != "":
+ self.logger.debug(result)
+
+ vims_test_result = ""
+ tempFile = os.path.join(self.test_dir, "temp.json")
+ try:
+ self.logger.debug("Trying to load test results")
+ with open(tempFile) as f:
+ vims_test_result = json.load(f)
+ f.close()
+ except:
+ self.logger.error("Unable to retrieve test results")
+
+ try:
+ os.remove(tempFile)
+ except:
+ self.logger.error("Deleting file failed")
+
+ if vims_test_result != '':
+ return {'status': 'PASS', 'result': vims_test_result}
+ else:
+ return {'status': 'FAIL', 'result': ''}
+
+ def clean(self):
+ # TODO
+ super(ImsVnf, self).clean()
diff --git a/functest/opnfv_tests/vnf/ims/orchestra_ims.py b/functest/opnfv_tests/vnf/ims/orchestra_ims.py
new file mode 100644
index 000000000..28f37f053
--- /dev/null
+++ b/functest/opnfv_tests/vnf/ims/orchestra_ims.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2016 Orange 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
+
+import json
+import os
+import requests
+import subprocess
+import time
+
+import functest.core.vnf_base as vnf_base
+import functest.utils.functest_logger as ft_logger
+import functest.utils.functest_utils as ft_utils
+from functest.utils.constants import CONST
+
+
+class ImsVnf(vnf_base.VnfOnBoardingBase):
+
+ def __init__(self, project='functest', case='orchestra_ims',
+ repo='', cmd=''):
+ super(ImsVnf, self).__init__(project, case, repo, cmd)
+ self.logger = ft_logger.Logger("vIMS").getLogger()
+ self.case_dir = os.path.join(CONST.functest_test, 'vnf/ims/')
+ self.data_dir = CONST.dir_vIMS_data
+ self.test_dir = CONST.dir_repo_vims_test
+
+ # vIMS Data directory creation
+ if not os.path.exists(self.data_dir):
+ os.makedirs(self.data_dir)
+
+ def deploy_orchestrator(self, **kwargs):
+ # TODO
+ # put your code here to deploy openbaton
+ # from the functest docker located on the jumphost
+ # you have admin rights on OpenStack SUT
+ # you can cretae a VM, spawn docker on the jumphost
+ # spawn docker on a VM in the SUT, ..up to you
+ #
+ # note: this step can be ignored
+ # if OpenBaton is part of the installer
+ self.logger.info("Deploy orchestrator: OK")
+
+ def deploy_vnf(self):
+ # deploy the VNF
+ # call openbaton to deploy the vIMS
+ self.logger.info("Deploy VNF: OK")
+
+ def test_vnf(self):
+ # Adaptations probably needed
+ # code used for cloudify_ims
+ # ruby client on jumphost calling the vIMS on the SUT
+ script = "source {0}venv_cloudify/bin/activate; "
+ script += "cd {0}; "
+ script += "cfy status | grep -Eo \"([0-9]{{1,3}}\.){{3}}[0-9]{{1,3}}\""
+ cmd = "/bin/bash -c '" + script.format(self.data_dir) + "'"
+
+ try:
+ self.logger.debug("Trying to get clearwater manager IP ... ")
+ mgr_ip = os.popen(cmd).read()
+ mgr_ip = mgr_ip.splitlines()[0]
+ except:
+ self.step_failure("Unable to retrieve the IP of the "
+ "cloudify manager server !")
+
+ api_url = "http://" + mgr_ip + "/api/v2"
+ dep_outputs = requests.get(api_url + "/deployments/" +
+ self.vnf.deployment_name + "/outputs")
+ dns_ip = dep_outputs.json()['outputs']['dns_ip']
+ ellis_ip = dep_outputs.json()['outputs']['ellis_ip']
+
+ ellis_url = "http://" + ellis_ip + "/"
+ url = ellis_url + "accounts"
+
+ params = {"password": "functest",
+ "full_name": "opnfv functest user",
+ "email": "functest@opnfv.fr",
+ "signup_code": "secret"}
+
+ rq = requests.post(url, data=params)
+ i = 20
+ while rq.status_code != 201 and i > 0:
+ rq = requests.post(url, data=params)
+ i = i - 1
+ time.sleep(10)
+
+ if rq.status_code == 201:
+ url = ellis_url + "session"
+ rq = requests.post(url, data=params)
+ cookies = rq.cookies
+
+ url = ellis_url + "accounts/" + params['email'] + "/numbers"
+ if cookies != "":
+ rq = requests.post(url, cookies=cookies)
+ i = 24
+ while rq.status_code != 200 and i > 0:
+ rq = requests.post(url, cookies=cookies)
+ i = i - 1
+ time.sleep(25)
+
+ if rq.status_code != 200:
+ self.step_failure("Unable to create a number: %s"
+ % rq.json()['reason'])
+
+ nameservers = ft_utils.get_resolvconf_ns()
+ resolvconf = ""
+ for ns in nameservers:
+ resolvconf += "\nnameserver " + ns
+
+ if dns_ip != "":
+ script = ('echo -e "nameserver ' + dns_ip + resolvconf +
+ '" > /etc/resolv.conf; ')
+ script += 'source /etc/profile.d/rvm.sh; '
+ script += 'cd {0}; '
+ script += ('rake test[{1}] SIGNUP_CODE="secret"')
+
+ cmd = ("/bin/bash -c '" +
+ script.format(self.data_dir, self.inputs["public_domain"]) +
+ "'")
+ output_file = "output.txt"
+ f = open(output_file, 'w+')
+ subprocess.call(cmd, shell=True, stdout=f,
+ stderr=subprocess.STDOUT)
+ f.close()
+
+ f = open(output_file, 'r')
+ result = f.read()
+ if result != "":
+ self.logger.debug(result)
+
+ vims_test_result = ""
+ tempFile = os.path.join(self.test_dir, "temp.json")
+ try:
+ self.logger.debug("Trying to load test results")
+ with open(tempFile) as f:
+ vims_test_result = json.load(f)
+ f.close()
+ except:
+ self.logger.error("Unable to retrieve test results")
+
+ try:
+ os.remove(tempFile)
+ except:
+ self.logger.error("Deleting file failed")
+
+ if vims_test_result != '':
+ return {'status': 'PASS', 'result': vims_test_result}
+ else:
+ return {'status': 'FAIL', 'result': ''}
+
+ def clean(self):
+ # TODO
+ super(ImsVnf, self).clean()
diff --git a/functest/opnfv_tests/vnf/ims/orchestrator.py b/functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py
index f3838f871..f3838f871 100644
--- a/functest/opnfv_tests/vnf/ims/orchestrator.py
+++ b/functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py
diff --git a/functest/opnfv_tests/vnf/ims/vims.py b/functest/opnfv_tests/vnf/ims/vims.py
deleted file mode 100755
index fe888b698..000000000
--- a/functest/opnfv_tests/vnf/ims/vims.py
+++ /dev/null
@@ -1,521 +0,0 @@
-#!/usr/bin/python
-# coding: utf8
-#######################################################################
-#
-# Copyright (c) 2015 Orange
-# valentin.boucher@orange.com
-#
-# 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
-########################################################################
-
-import datetime
-import json
-import os
-import pprint
-import subprocess
-import time
-
-import argparse
-import keystoneclient.v2_0.client as ksclient
-import novaclient.client as nvclient
-import requests
-from neutronclient.v2_0 import client as ntclient
-
-import functest.utils.functest_logger as ft_logger
-import functest.utils.functest_utils as ft_utils
-import functest.utils.openstack_utils as os_utils
-from clearwater import Clearwater
-from orchestrator import Orchestrator
-import functest.utils.functest_constants as ft_constants
-
-pp = pprint.PrettyPrinter(indent=4)
-
-
-parser = argparse.ArgumentParser()
-parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
-parser.add_argument("-r", "--report",
- help="Create json result file",
- action="store_true")
-parser.add_argument("-n", "--noclean",
- help="Don't clean the created resources for this test.",
- action="store_true")
-args = parser.parse_args()
-
-""" logging configuration """
-logger = ft_logger.Logger("vIMS").getLogger()
-
-
-# Cloudify parameters
-VIMS_DIR = os.path.join(ft_constants.FUNCTEST_TEST_DIR, 'vnf/ims/')
-VIMS_DATA_DIR = ft_constants.VIMS_DATA_DIR
-VIMS_TEST_DIR = ft_constants.VIMS_TEST_DIR
-VIMS_TENANT_NAME = ft_constants.VIMS_TENANT_NAME
-VIMS_TENANT_DESCRIPTION = ft_constants.VIMS_TENANT_DESCRIPTION
-VIMS_IMAGES = ft_constants.VIMS_IMAGES
-
-CFY_MANAGER_BLUEPRINT = ft_constants.CFY_MANAGER_BLUEPRINT
-CFY_MANAGER_REQUIERMENTS = ft_constants.CFY_MANAGER_REQUIERMENTS
-CFY_INPUTS = ft_constants.CFY_INPUTS
-
-CW_BLUEPRINT = ft_constants.CW_BLUEPRINT
-CW_DEPLOYMENT_NAME = ft_constants.CW_DEPLOYMENT_NAME
-CW_INPUTS = ft_constants.CW_INPUTS
-CW_REQUIERMENTS = ft_constants.CW_REQUIERMENTS
-
-CFY_DEPLOYMENT_DURATION = 0
-CW_DEPLOYMENT_DURATION = 0
-
-TESTCASE_START_TIME = time.time()
-RESULTS = {'orchestrator': {'duration': 0, 'result': ''},
- 'vIMS': {'duration': 0, 'result': ''},
- 'sig_test': {'duration': 0, 'result': ''}}
-
-
-def download_and_add_image_on_glance(glance, image_name, image_url):
- dest_path = os.path.join(VIMS_DATA_DIR, "tmp/")
- if not os.path.exists(dest_path):
- os.makedirs(dest_path)
- file_name = image_url.rsplit('/')[-1]
- if not ft_utils.download_url(image_url, dest_path):
- logger.error("Failed to download image %s" % file_name)
- return False
-
- image = os_utils.create_glance_image(
- glance, image_name, dest_path + file_name)
- if not image:
- logger.error("Failed to upload image on glance")
- return False
-
- return image
-
-
-def step_failure(step_name, error_msg):
- logger.error(error_msg)
- set_result(step_name, 0, error_msg)
- status = "FAIL"
- # in case of failure starting and stoping time are not correct
- stop_time = time.time()
- if step_name == "sig_test":
- status = "PASS"
- ft_utils.push_results_to_db("functest",
- "vims",
- TESTCASE_START_TIME,
- stop_time,
- status,
- RESULTS)
- exit(-1)
-
-
-def set_result(step_name, duration=0, result=""):
- RESULTS[step_name] = {'duration': duration, 'result': result}
-
-
-def test_clearwater():
- script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
- script += "cd " + VIMS_DATA_DIR + "; "
- script += "cfy status | grep -Eo \"([0-9]{1,3}\.){3}[0-9]{1,3}\""
- cmd = "/bin/bash -c '" + script + "'"
-
- try:
- logger.debug("Trying to get clearwater manager IP ... ")
- mgr_ip = os.popen(cmd).read()
- mgr_ip = mgr_ip.splitlines()[0]
- except:
- step_failure("sig_test", "Unable to retrieve the IP of the "
- "cloudify manager server !")
-
- api_url = "http://" + mgr_ip + "/api/v2"
- dep_outputs = requests.get(api_url + "/deployments/" +
- CW_DEPLOYMENT_NAME + "/outputs")
- dns_ip = dep_outputs.json()['outputs']['dns_ip']
- ellis_ip = dep_outputs.json()['outputs']['ellis_ip']
-
- ellis_url = "http://" + ellis_ip + "/"
- url = ellis_url + "accounts"
-
- params = {"password": "functest",
- "full_name": "opnfv functest user",
- "email": "functest@opnfv.fr",
- "signup_code": "secret"}
-
- rq = requests.post(url, data=params)
- i = 20
- while rq.status_code != 201 and i > 0:
- rq = requests.post(url, data=params)
- i = i - 1
- time.sleep(10)
-
- if rq.status_code == 201:
- url = ellis_url + "session"
- rq = requests.post(url, data=params)
- cookies = rq.cookies
-
- url = ellis_url + "accounts/" + params['email'] + "/numbers"
- if cookies != "":
- rq = requests.post(url, cookies=cookies)
- i = 24
- while rq.status_code != 200 and i > 0:
- rq = requests.post(url, cookies=cookies)
- i = i - 1
- time.sleep(25)
-
- if rq.status_code != 200:
- step_failure("sig_test", "Unable to create a number: %s"
- % rq.json()['reason'])
-
- start_time_ts = time.time()
- end_time_ts = start_time_ts
- logger.info("vIMS functional test Start Time:'%s'" % (
- datetime.datetime.fromtimestamp(start_time_ts).strftime(
- '%Y-%m-%d %H:%M:%S')))
- nameservers = ft_utils.get_resolvconf_ns()
- resolvconf = ""
- for ns in nameservers:
- resolvconf += "\nnameserver " + ns
-
- if dns_ip != "":
- script = ('echo -e "nameserver ' + dns_ip + resolvconf +
- '" > /etc/resolv.conf; ')
- script += 'source /etc/profile.d/rvm.sh; '
- script += 'cd ' + VIMS_TEST_DIR + '; '
- script += ('rake test[' + CW_INPUTS["public_domain"] +
- '] SIGNUP_CODE="secret"')
-
- cmd = "/bin/bash -c '" + script + "'"
- output_file = "output.txt"
- f = open(output_file, 'w+')
- subprocess.call(cmd, shell=True, stdout=f,
- stderr=subprocess.STDOUT)
- f.close()
- end_time_ts = time.time()
- duration = round(end_time_ts - start_time_ts, 1)
- logger.info("vIMS functional test duration:'%s'" % duration)
- f = open(output_file, 'r')
- result = f.read()
- if result != "" and logger:
- logger.debug(result)
-
- vims_test_result = ""
- tempFile = os.path.join(VIMS_TEST_DIR, "temp.json")
- try:
- logger.debug("Trying to load test results")
- with open(tempFile) as f:
- vims_test_result = json.load(f)
- f.close()
- except:
- logger.error("Unable to retrieve test results")
-
- set_result("sig_test", duration, vims_test_result)
-
- # success criteria for vIMS (for Brahmaputra)
- # - orchestrator deployed
- # - VNF deployed
- # TODO use test criteria defined in config file
- status = "FAIL"
- try:
- if (RESULTS['orchestrator']['duration'] > 0 and
- RESULTS['vIMS']['duration'] > 0):
- status = "PASS"
- except:
- logger.error("Unable to set test status")
-
- ft_utils.push_results_to_db("functest",
- "vims",
- TESTCASE_START_TIME,
- end_time_ts,
- status,
- RESULTS)
-
- try:
- os.remove(tempFile)
- except:
- logger.error("Deleting file failed")
-
-
-def main():
-
- # ############### GENERAL INITIALISATION ################
-
- if not os.path.exists(VIMS_DATA_DIR):
- os.makedirs(VIMS_DATA_DIR)
-
- ks_creds = os_utils.get_credentials("keystone")
- nv_creds = os_utils.get_credentials("nova")
- nt_creds = os_utils.get_credentials("neutron")
-
- logger.info("Prepare OpenStack plateform (create tenant and user)")
- keystone = ksclient.Client(**ks_creds)
-
- user_id = os_utils.get_user_id(keystone, ks_creds['username'])
- if user_id == '':
- step_failure("init", "Error : Failed to get id of " +
- ks_creds['username'])
-
- tenant_id = os_utils.create_tenant(
- keystone, VIMS_TENANT_NAME, VIMS_TENANT_DESCRIPTION)
- if not tenant_id:
- step_failure("init", "Error : Failed to create " +
- VIMS_TENANT_NAME + " tenant")
-
- roles_name = ["admin", "Admin"]
- role_id = ''
- for role_name in roles_name:
- if role_id == '':
- role_id = os_utils.get_role_id(keystone, role_name)
-
- if role_id == '':
- logger.error("Error : Failed to get id for %s role" % role_name)
-
- if not os_utils.add_role_user(keystone, user_id, role_id, tenant_id):
- logger.error("Error : Failed to add %s on tenant" %
- ks_creds['username'])
-
- user_id = os_utils.create_user(
- keystone, VIMS_TENANT_NAME, VIMS_TENANT_NAME, None, tenant_id)
- if not user_id:
- logger.error("Error : Failed to create %s user" % VIMS_TENANT_NAME)
-
- logger.info("Update OpenStack creds informations")
- ks_creds.update({
- "username": VIMS_TENANT_NAME,
- "password": VIMS_TENANT_NAME,
- "tenant_name": VIMS_TENANT_NAME,
- })
-
- nt_creds.update({
- "tenant_name": VIMS_TENANT_NAME,
- })
-
- nv_creds.update({
- "project_id": VIMS_TENANT_NAME,
- })
-
- logger.info("Upload some OS images if it doesn't exist")
- glance = os_utils.get_glance_client()
-
- for img in VIMS_IMAGES.keys():
- image_name = VIMS_IMAGES[img]['image_name']
- image_url = VIMS_IMAGES[img]['image_url']
-
- image_id = os_utils.get_image_id(glance, image_name)
-
- if image_id == '':
- logger.info("""%s image doesn't exist on glance repository. Try
- downloading this image and upload on glance !""" % image_name)
- image_id = download_and_add_image_on_glance(
- glance, image_name, image_url)
-
- if image_id == '':
- step_failure(
- "init",
- "Error : Failed to find or upload required OS "
- "image for this deployment")
-
- nova = nvclient.Client("2", **nv_creds)
-
- logger.info("Update security group quota for this tenant")
- neutron = ntclient.Client(**nt_creds)
- if not os_utils.update_sg_quota(neutron, tenant_id, 50, 100):
- step_failure(
- "init",
- "Failed to update security group quota for tenant " +
- VIMS_TENANT_NAME)
-
- # ############### CLOUDIFY INITIALISATION ################
- public_auth_url = keystone.service_catalog.url_for(
- service_type='identity', endpoint_type='publicURL')
-
- cfy = Orchestrator(VIMS_DATA_DIR, CFY_INPUTS)
-
- cfy.set_credentials(username=ks_creds['username'], password=ks_creds[
- 'password'], tenant_name=ks_creds['tenant_name'],
- auth_url=public_auth_url)
-
- logger.info("Collect flavor id for cloudify manager server")
- nova = nvclient.Client("2", **nv_creds)
-
- flavor_name = "m1.large"
- flavor_id = os_utils.get_flavor_id(nova, flavor_name)
- for requirement in CFY_MANAGER_REQUIERMENTS:
- if requirement == 'ram_min':
- flavor_id = os_utils.get_flavor_id_by_ram_range(
- nova, CFY_MANAGER_REQUIERMENTS['ram_min'], 10000)
-
- if flavor_id == '':
- logger.error(
- "Failed to find %s flavor. "
- "Try with ram range default requirement !" % flavor_name)
- flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
-
- if flavor_id == '':
- step_failure("orchestrator",
- "Failed to find required flavor for this deployment")
-
- cfy.set_flavor_id(flavor_id)
-
- image_name = "centos_7"
- image_id = os_utils.get_image_id(glance, image_name)
- for requirement in CFY_MANAGER_REQUIERMENTS:
- if requirement == 'os_image':
- image_id = os_utils.get_image_id(
- glance, CFY_MANAGER_REQUIERMENTS['os_image'])
-
- if image_id == '':
- step_failure(
- "orchestrator",
- "Error : Failed to find required OS image for cloudify manager")
-
- cfy.set_image_id(image_id)
-
- ext_net = os_utils.get_external_net(neutron)
- if not ext_net:
- step_failure("orchestrator", "Failed to get external network")
-
- cfy.set_external_network_name(ext_net)
-
- ns = ft_utils.get_resolvconf_ns()
- if ns:
- cfy.set_nameservers(ns)
-
- if 'compute' in nova.client.services_url:
- cfy.set_nova_url(nova.client.services_url['compute'])
- if neutron.httpclient.endpoint_url is not None:
- cfy.set_neutron_url(neutron.httpclient.endpoint_url)
-
- logger.info("Prepare virtualenv for cloudify-cli")
- cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
- ft_utils.execute_command(cmd)
- time.sleep(3)
- cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
- ft_utils.execute_command(cmd)
-
- cfy.download_manager_blueprint(
- CFY_MANAGER_BLUEPRINT['url'], CFY_MANAGER_BLUEPRINT['branch'])
-
- # ############### CLOUDIFY DEPLOYMENT ################
- start_time_ts = time.time()
- end_time_ts = start_time_ts
- logger.info("Cloudify deployment Start Time:'%s'" % (
- datetime.datetime.fromtimestamp(start_time_ts).strftime(
- '%Y-%m-%d %H:%M:%S')))
-
- error = cfy.deploy_manager()
- if error:
- step_failure("orchestrator", error)
-
- end_time_ts = time.time()
- duration = round(end_time_ts - start_time_ts, 1)
- logger.info("Cloudify deployment duration:'%s'" % duration)
- set_result("orchestrator", duration, "")
-
- # ############### CLEARWATER INITIALISATION ################
-
- cw = Clearwater(CW_INPUTS, cfy, logger)
-
- logger.info("Collect flavor id for all clearwater vm")
- nova = nvclient.Client("2", **nv_creds)
-
- flavor_name = "m1.small"
- flavor_id = os_utils.get_flavor_id(nova, flavor_name)
- for requirement in CW_REQUIERMENTS:
- if requirement == 'ram_min' and flavor_id == '':
- flavor_id = os_utils.get_flavor_id_by_ram_range(
- nova, CW_REQUIERMENTS['ram_min'], 4500)
-
- if flavor_id == '':
- logger.error(
- "Failed to find %s flavor. Try with ram range "
- "default requirement !" % flavor_name)
- flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
-
- if flavor_id == '':
- step_failure(
- "vIMS", "Failed to find required flavor for this deployment")
-
- cw.set_flavor_id(flavor_id)
-
- image_name = "ubuntu_14.04"
- image_id = os_utils.get_image_id(glance, image_name)
- for requirement in CW_REQUIERMENTS:
- if requirement == 'os_image':
- image_id = os_utils.get_image_id(
- glance, CW_REQUIERMENTS['os_image'])
-
- if image_id == '':
- step_failure(
- "vIMS",
- "Error : Failed to find required OS image for cloudify manager")
-
- cw.set_image_id(image_id)
-
- ext_net = os_utils.get_external_net(neutron)
- if not ext_net:
- step_failure("vIMS", "Failed to get external network")
-
- cw.set_external_network_name(ext_net)
-
- # ############### CLEARWATER DEPLOYMENT ################
-
- start_time_ts = time.time()
- end_time_ts = start_time_ts
- logger.info("vIMS VNF deployment Start Time:'%s'" % (
- datetime.datetime.fromtimestamp(start_time_ts).strftime(
- '%Y-%m-%d %H:%M:%S')))
-
- error = cw.deploy_vnf(CW_BLUEPRINT)
- if error:
- step_failure("vIMS", error)
-
- end_time_ts = time.time()
- duration = round(end_time_ts - start_time_ts, 1)
- logger.info("vIMS VNF deployment duration:'%s'" % duration)
- set_result("vIMS", duration, "")
-
- # ############### CLEARWATER TEST ################
-
- test_clearwater()
-
- # ########## CLEARWATER UNDEPLOYMENT ############
-
- cw.undeploy_vnf()
-
- # ########### CLOUDIFY UNDEPLOYMENT #############
-
- cfy.undeploy_manager()
-
- # ############## GENERAL CLEANUP ################
- if args.noclean:
- exit(0)
-
- ks_creds = os_utils.get_credentials("keystone")
-
- keystone = ksclient.Client(**ks_creds)
-
- logger.info("Removing %s tenant .." % CFY_INPUTS['keystone_tenant_name'])
- tenant_id = os_utils.get_tenant_id(
- keystone, CFY_INPUTS['keystone_tenant_name'])
- if tenant_id == '':
- logger.error("Error : Failed to get id of %s tenant" %
- CFY_INPUTS['keystone_tenant_name'])
- else:
- if not os_utils.delete_tenant(keystone, tenant_id):
- logger.error("Error : Failed to remove %s tenant" %
- CFY_INPUTS['keystone_tenant_name'])
-
- logger.info("Removing %s user .." % CFY_INPUTS['keystone_username'])
- user_id = os_utils.get_user_id(
- keystone, CFY_INPUTS['keystone_username'])
- if user_id == '':
- logger.error("Error : Failed to get id of %s user" %
- CFY_INPUTS['keystone_username'])
- else:
- if not os_utils.delete_user(keystone, user_id):
- logger.error("Error : Failed to remove %s user" %
- CFY_INPUTS['keystone_username'])
-
-
-if __name__ == '__main__':
- main()
diff --git a/functest/tests/unit/cli/__init__.py b/functest/tests/unit/cli/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/tests/unit/cli/__init__.py
diff --git a/functest/tests/unit/cli/commands/__init__.py b/functest/tests/unit/cli/commands/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/tests/unit/cli/commands/__init__.py
diff --git a/functest/tests/unit/cli/commands/test_cli_env.py b/functest/tests/unit/cli/commands/test_cli_env.py
new file mode 100644
index 000000000..f70761dcd
--- /dev/null
+++ b/functest/tests/unit/cli/commands/test_cli_env.py
@@ -0,0 +1,131 @@
+#!/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
+
+import logging
+import unittest
+
+from git.exc import NoSuchPathError
+import mock
+
+mock.patch('logging.FileHandler').start() # noqa
+from functest.cli.commands import cli_env
+from functest.utils.constants import CONST
+from functest.tests.unit import test_utils
+
+
+class CliEnvTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.cli_environ = cli_env.CliEnv()
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_prepare_default(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/prepare_env.py start" %
+ CONST.dir_repo_functest)
+ self.cli_environ.prepare()
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_prepare_missing_status(self, mock_ft_utils, mock_os):
+ with mock.patch('__builtin__.raw_input', return_value="y"), \
+ mock.patch('functest.cli.commands.cli_testcase.os.remove') \
+ as mock_os_remove:
+ cmd = ("python %s/functest/ci/prepare_env.py start" %
+ CONST.dir_repo_functest)
+ self.cli_environ.prepare()
+ mock_os_remove.assert_called_once_with(CONST.env_active)
+ mock_ft_utils.assert_called_with(cmd)
+
+ def _test_show_missing_env_var(self, var, *args):
+ if var == 'INSTALLER_TYPE':
+ CONST.INSTALLER_TYPE = None
+ reg_string = "| INSTALLER: Unknown, \S+\s*|"
+ elif var == 'INSTALLER_IP':
+ CONST.INSTALLER_IP = None
+ reg_string = "| INSTALLER: \S+, Unknown\s*|"
+ elif var == 'SCENARIO':
+ CONST.DEPLOY_SCENARIO = None
+ reg_string = "| SCENARIO: Unknown\s*|"
+ elif var == 'NODE':
+ CONST.NODE_NAME = None
+ reg_string = "| POD: Unknown\s*|"
+ elif var == 'BUILD_TAG':
+ CONST.BUILD_TAG = None
+ reg_string = "| BUILD TAG: None|"
+ elif var == 'DEBUG':
+ CONST.CI_DEBUG = None
+ reg_string = "| DEBUG FLAG: false\s*|"
+ elif var == 'STATUS':
+ reg_string = "| STATUS: not ready\s*|"
+
+ with mock.patch('functest.cli.commands.cli_env.click.echo') \
+ as mock_click_echo:
+ self.cli_environ.show()
+ mock_click_echo.assert_called_with(test_utils.
+ RegexMatch(reg_string))
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_installer_type(self, *args):
+ self._test_show_missing_env_var('INSTALLER_TYPE', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_installer_ip(self, *args):
+ self._test_show_missing_env_var('INSTALLER_IP', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_scenario(self, *args):
+ self._test_show_missing_env_var('SCENARIO', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_node(self, *args):
+ self._test_show_missing_env_var('NODE', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_build_tag(self, *args):
+ self._test_show_missing_env_var('BUILD_TAG', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_debug(self, *args):
+ self._test_show_missing_env_var('DEBUG', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ @mock.patch('functest.cli.commands.cli_env.os.path.isfile',
+ return_value=False)
+ def test_show_missing_environment(self, *args):
+ self._test_show_missing_env_var('STATUS', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.os.path.exists',
+ return_value=False)
+ def test_show_missing_git_repo_dir(self, *args):
+ CONST.dir_repo_functest = None
+ self.assertRaises(NoSuchPathError, lambda: self.cli_environ.show())
+
+ @mock.patch('functest.cli.commands.cli_env.click.echo')
+ @mock.patch('functest.cli.commands.cli_env.os.path.isfile',
+ return_value=True)
+ def test_status_environment_present(self, mock_path, mock_click_echo):
+ self.assertEqual(self.cli_environ.status(), 0)
+ mock_click_echo.assert_called_with("Functest environment"
+ " ready to run tests.\n")
+
+ @mock.patch('functest.cli.commands.cli_env.click.echo')
+ @mock.patch('functest.cli.commands.cli_env.os.path.isfile',
+ return_value=False)
+ def test_status_environment_absent(self, mock_path, mock_click_echo):
+ self.assertEqual(self.cli_environ.status(), 1)
+ mock_click_echo.assert_called_with("Functest environment"
+ " is not installed.\n")
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/commands/test_cli_os.py b/functest/tests/unit/cli/commands/test_cli_os.py
new file mode 100644
index 000000000..f0e58c676
--- /dev/null
+++ b/functest/tests/unit/cli/commands/test_cli_os.py
@@ -0,0 +1,238 @@
+#!/usr/bin/env python
+#
+# jose.lausuch@ericsson.com
+# 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
+#
+
+import logging
+import unittest
+import os
+
+import mock
+
+from functest.cli.commands import cli_os
+from functest.utils.constants import CONST
+
+
+class CliOpenStackTesting(unittest.TestCase):
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.endpoint_ip = 'test_ip'
+ self.os_auth_url = 'http://test_ip:test_port/v2.0'
+ self.installer_type = 'test_installer_type'
+ self.installer_ip = 'test_installer_ip'
+ self.openstack_creds = 'test_openstack_creds'
+ self.dir_repo_functest = 'test_dir_repo_functest'
+ self.snapshot_file = 'test_snapshot_file'
+ self.cli_os = cli_os.CliOpenStack()
+
+ def test_ping_endpoint_default(self):
+ self.cli_os.os_auth_url = self.os_auth_url
+ self.cli_os.endpoint_ip = self.endpoint_ip
+ with mock.patch('functest.cli.commands.cli_os.os.system',
+ return_value=0):
+ self.assertEqual(self.cli_os.ping_endpoint(), 0)
+
+ @mock.patch('functest.cli.commands.cli_os.exit', side_effect=Exception)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_ping_endpoint_missing_auth_url(self, mock_click_echo,
+ mock_exit):
+ with self.assertRaises(Exception):
+ self.cli_os.os_auth_url = None
+ self.cli_os.ping_endpoint()
+ mock_click_echo.assert_called_once_with("Source the OpenStack "
+ "credentials first '. "
+ "$creds'")
+
+ @mock.patch('functest.cli.commands.cli_os.exit')
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_ping_endpoint_os_system_fails(self, mock_click_echo,
+ mock_exit):
+ self.cli_os.os_auth_url = self.os_auth_url
+ self.cli_os.endpoint_ip = self.endpoint_ip
+ with mock.patch('functest.cli.commands.cli_os.os.system',
+ return_value=1):
+ self.cli_os.ping_endpoint()
+ mock_click_echo.assert_called_once_with("Cannot talk to the "
+ "endpoint %s\n" %
+ self.endpoint_ip)
+ mock_exit.assert_called_once_with(0)
+
+ @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_fetch_credentials_default(self, mock_click_echo,
+ mock_os_path,
+ mock_ftutils_execute):
+ CONST.INSTALLER_TYPE = self.installer_type
+ CONST.INSTALLER_IP = self.installer_ip
+ cmd = ("%s/releng/utils/fetch_os_creds.sh -d %s -i %s -a %s"
+ % (CONST.dir_repos,
+ self.openstack_creds,
+ self.installer_type,
+ self.installer_ip))
+ self.cli_os.openstack_creds = self.openstack_creds
+ self.cli_os.fetch_credentials()
+ mock_click_echo.assert_called_once_with("Fetching credentials from "
+ "installer node '%s' with "
+ "IP=%s.." %
+ (self.installer_type,
+ self.installer_ip))
+ mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+ @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_fetch_credentials_missing_installer_type(self, mock_click_echo,
+ mock_os_path,
+ mock_ftutils_execute):
+ installer_type = None
+ installer_ip = self.installer_ip
+ CONST.INSTALLER_TYPE = installer_type
+ CONST.INSTALLER_IP = installer_ip
+ cmd = ("%s/releng/utils/fetch_os_creds.sh -d %s -i %s -a %s"
+ % (CONST.dir_repos,
+ self.openstack_creds,
+ installer_type,
+ installer_ip))
+ self.cli_os.openstack_creds = self.openstack_creds
+ self.cli_os.fetch_credentials()
+ mock_click_echo.assert_any_call("The environment variable "
+ "'INSTALLER_TYPE' is not"
+ "defined. Please export it")
+ mock_click_echo.assert_any_call("Fetching credentials from "
+ "installer node '%s' with "
+ "IP=%s.." %
+ (installer_type,
+ installer_ip))
+ mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+ @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_fetch_credentials_missing_installer_ip(self, mock_click_echo,
+ mock_os_path,
+ mock_ftutils_execute):
+ installer_type = self.installer_type
+ installer_ip = None
+ CONST.INSTALLER_TYPE = installer_type
+ CONST.INSTALLER_IP = installer_ip
+ cmd = ("%s/releng/utils/fetch_os_creds.sh -d %s -i %s -a %s"
+ % (CONST.dir_repos,
+ self.openstack_creds,
+ installer_type,
+ installer_ip))
+ self.cli_os.openstack_creds = self.openstack_creds
+ self.cli_os.fetch_credentials()
+ mock_click_echo.assert_any_call("The environment variable "
+ "'INSTALLER_IP' is not"
+ "defined. Please export it")
+ mock_click_echo.assert_any_call("Fetching credentials from "
+ "installer node '%s' with "
+ "IP=%s.." %
+ (installer_type,
+ installer_ip))
+ mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+ @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+ def test_check(self, mock_ftutils_execute):
+ with mock.patch.object(self.cli_os, 'ping_endpoint'):
+ CONST.dir_repo_functest = self.dir_repo_functest
+ cmd = CONST.dir_repo_functest + "/functest/ci/check_os.sh"
+ self.cli_os.check()
+ mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_snapshot_create(self, mock_click_echo, mock_os_path):
+ with mock.patch.object(self.cli_os, 'ping_endpoint'), \
+ mock.patch('functest.cli.commands.cli_os.os_snapshot.main') \
+ as mock_os_snapshot:
+ self.cli_os.snapshot_create()
+ mock_click_echo.assert_called_once_with("Generating Openstack "
+ "snapshot...")
+ self.assertTrue(mock_os_snapshot.called)
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_snapshot_create_overwrite(self, mock_click_echo, mock_os_path):
+ with mock.patch('__builtin__.raw_input', return_value="y") \
+ as mock_raw_input, \
+ mock.patch.object(self.cli_os, 'ping_endpoint'), \
+ mock.patch('functest.cli.commands.cli_os.os_snapshot.main') \
+ as mock_os_snapshot:
+ self.cli_os.snapshot_create()
+ mock_click_echo.assert_called_once_with("Generating Openstack "
+ "snapshot...")
+ mock_raw_input.assert_any_call("It seems there is already an "
+ "OpenStack snapshot. Do you want "
+ "to overwrite it with the current "
+ "OpenStack status? [y|n]\n")
+ self.assertTrue(mock_os_snapshot.called)
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_snapshot_show_missing_snap(self, mock_click_echo, mock_os_path):
+ self.cli_os.snapshot_show()
+ mock_click_echo.assert_called_once_with("There is no OpenStack "
+ "snapshot created. To create "
+ "one run the command "
+ "'functest openstack "
+ "snapshot-create'")
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_snapshot_show_default(self, mock_click_echo, mock_os_path):
+ with mock.patch('__builtin__.open', mock.mock_open(read_data='0')) \
+ as m:
+ self.cli_os.snapshot_file = self.snapshot_file
+ self.cli_os.snapshot_show()
+ m.assert_called_once_with(self.snapshot_file, 'r')
+ mock_click_echo.assert_called_once_with("\n0")
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_clean(self, mock_click_echo, mock_os_path):
+ with mock.patch.object(self.cli_os, 'ping_endpoint'), \
+ mock.patch('functest.cli.commands.cli_os.os_clean.main') \
+ as mock_os_clean:
+ self.cli_os.clean()
+ self.assertTrue(mock_os_clean.called)
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_clean_missing_file(self, mock_click_echo, mock_os_path):
+ with mock.patch.object(self.cli_os, 'ping_endpoint'):
+ self.cli_os.clean()
+ mock_click_echo.assert_called_once_with("Not possible to clean "
+ "OpenStack without a "
+ "snapshot. This could "
+ "cause problems. "
+ "Run first the command "
+ "'functest openstack "
+ "snapshot-create'")
+
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_show_credentials(self, mock_click_echo):
+ key = 'OS_KEY'
+ value = 'OS_VALUE'
+ with mock.patch.dict(os.environ, {key: value}):
+ self.cli_os.show_credentials()
+ mock_click_echo.assert_any_call("{}={}".format(key, value))
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/commands/test_cli_testcase.py b/functest/tests/unit/cli/commands/test_cli_testcase.py
new file mode 100644
index 000000000..39c8139d7
--- /dev/null
+++ b/functest/tests/unit/cli/commands/test_cli_testcase.py
@@ -0,0 +1,103 @@
+#!/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
+
+
+import logging
+import unittest
+
+import mock
+
+from functest.cli.commands import cli_testcase
+from functest.utils.constants import CONST
+
+
+class CliTestCasesTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.testname = 'testname'
+ with mock.patch('functest.cli.commands.cli_testcase.tb'):
+ self.cli_tests = cli_testcase.CliTestcase()
+
+ @mock.patch('functest.cli.commands.cli_testcase.vacation.main')
+ def test_run_vacation(self, mock_method):
+ self.cli_tests.run('vacation')
+ self.assertTrue(mock_method.called)
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+ def test_run_missing_env_file(self, mock_click_echo, mock_os):
+ self.cli_tests.run(self.testname)
+ mock_click_echo.assert_called_with("Functest environment is not ready."
+ " Run first 'functest env prepare'")
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_run_default(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-n -r ", self.testname))
+ self.cli_tests.run(self.testname, noclean=True, report=True)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_run_noclean_missing_report(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-n ", self.testname))
+ self.cli_tests.run(self.testname, noclean=True, report=False)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_run_report_missing_noclean(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-r ", self.testname))
+ self.cli_tests.run(self.testname, noclean=False, report=True)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_run_missing_noclean_report(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "", self.testname))
+ self.cli_tests.run(self.testname, noclean=False, report=False)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+ def test_list(self, mock_click_echo):
+ with mock.patch.object(self.cli_tests.tiers, 'get_tiers',
+ return_value=[]):
+ self.cli_tests.list()
+ mock_click_echo.assert_called_with("")
+
+ @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+ def test_show_default_desc_none(self, mock_click_echo):
+ with mock.patch.object(self.cli_tests.tiers, 'get_test',
+ return_value=None):
+ self.cli_tests.show(self.testname)
+ mock_click_echo.assert_any_call("The test case '%s' "
+ "does not exist or is"
+ " not supported."
+ % self.testname)
+
+ @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+ def test_show_default(self, mock_click_echo):
+ mock_obj = mock.Mock()
+ with mock.patch.object(self.cli_tests.tiers, 'get_test',
+ return_value=mock_obj):
+ self.cli_tests.show(self.testname)
+ mock_click_echo.assert_called_with(mock_obj)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/commands/test_cli_tier.py b/functest/tests/unit/cli/commands/test_cli_tier.py
new file mode 100644
index 000000000..802359f16
--- /dev/null
+++ b/functest/tests/unit/cli/commands/test_cli_tier.py
@@ -0,0 +1,130 @@
+#!/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
+
+
+import logging
+import unittest
+
+import mock
+
+from functest.cli.commands import cli_tier
+from functest.utils.constants import CONST
+
+
+class CliTierTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.tiername = 'tiername'
+ self.testnames = 'testnames'
+ with mock.patch('functest.cli.commands.cli_tier.tb'):
+ self.cli_tier = cli_tier.CliTier()
+
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_list(self, mock_click_echo):
+ with mock.patch.object(self.cli_tier.tiers, 'get_tiers',
+ return_value=[]):
+ self.cli_tier.list()
+ mock_click_echo.assert_called_with("")
+
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_show_default(self, mock_click_echo):
+ with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+ return_value=self.tiername):
+ self.cli_tier.show(self.tiername)
+ mock_click_echo.assert_called_with(self.tiername)
+
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_show_missing_tier(self, mock_click_echo):
+ with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+ return_value=None), \
+ mock.patch.object(self.cli_tier.tiers, 'get_tier_names',
+ return_value='tiernames'):
+ self.cli_tier.show(self.tiername)
+ mock_click_echo.assert_called_with("The tier with name '%s' does "
+ "not exist. Available tiers are"
+ ":\n %s\n" % (self.tiername,
+ 'tiernames'))
+
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_gettests_default(self, mock_click_echo):
+ mock_obj = mock.Mock()
+ attrs = {'get_test_names.return_value': self.testnames}
+ mock_obj.configure_mock(**attrs)
+
+ with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+ return_value=mock_obj):
+ self.cli_tier.gettests(self.tiername)
+ mock_click_echo.assert_called_with("Test cases in tier "
+ "'%s':\n %s\n" % (self.tiername,
+ self.testnames
+ ))
+
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_gettests_missing_tier(self, mock_click_echo):
+ with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+ return_value=None), \
+ mock.patch.object(self.cli_tier.tiers, 'get_tier_names',
+ return_value='tiernames'):
+ self.cli_tier.gettests(self.tiername)
+ mock_click_echo.assert_called_with("The tier with name '%s' does "
+ "not exist. Available tiers are"
+ ":\n %s\n" % (self.tiername,
+ 'tiernames'))
+
+ @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_run_missing_env_file(self, mock_click_echo, mock_os):
+ self.cli_tier.run(self.tiername)
+ mock_click_echo.assert_called_with("Functest environment is not ready."
+ " Run first 'functest env prepare'")
+
+ @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+ def test_run_default(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-n -r ",
+ self.tiername))
+ self.cli_tier.run(self.tiername, noclean=True, report=True)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+ def test_run_report_missing_noclean(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-r ",
+ self.tiername))
+ self.cli_tier.run(self.tiername, noclean=False, report=True)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+ def test_run_noclean_missing_report(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-n ",
+ self.tiername))
+ self.cli_tier.run(self.tiername, noclean=True, report=False)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+ def test_run_missing_noclean_report(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "",
+ self.tiername))
+ self.cli_tier.run(self.tiername, noclean=False, report=False)
+ mock_ft_utils.assert_called_with(cmd)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/test_cli_base.py b/functest/tests/unit/cli/test_cli_base.py
new file mode 100644
index 000000000..fe065c2aa
--- /dev/null
+++ b/functest/tests/unit/cli/test_cli_base.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2016 Orange 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
+
+import logging
+import unittest
+
+import mock
+from click.testing import CliRunner
+
+with mock.patch('functest.cli.commands.cli_testcase.CliTestcase.__init__',
+ mock.Mock(return_value=None)), \
+ mock.patch('functest.cli.commands.cli_tier.CliTier.__init__',
+ mock.Mock(return_value=None)):
+ from functest.cli import cli_base
+
+
+class CliBaseTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.runner = CliRunner()
+ self._openstack = cli_base._openstack
+ self._env = cli_base._env
+ self._testcase = cli_base._testcase
+ self._tier = cli_base._tier
+
+ def test_os_check(self):
+ with mock.patch.object(self._openstack, 'check') as mock_method:
+ result = self.runner.invoke(cli_base.os_check)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_os_snapshot_create(self):
+ with mock.patch.object(self._openstack, 'snapshot_create') \
+ as mock_method:
+ result = self.runner.invoke(cli_base.os_snapshot_create)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_os_snapshot_show(self):
+ with mock.patch.object(self._openstack, 'snapshot_show') \
+ as mock_method:
+ result = self.runner.invoke(cli_base.os_snapshot_show)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_os_clean(self):
+ with mock.patch.object(self._openstack, 'clean') as mock_method:
+ result = self.runner.invoke(cli_base.os_clean)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_os_show_credentials(self):
+ with mock.patch.object(self._openstack, 'show_credentials') \
+ as mock_method:
+ result = self.runner.invoke(cli_base.os_show_credentials)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_os_fetch_rc(self):
+ with mock.patch.object(self._openstack, 'fetch_credentials') \
+ as mock_method:
+ result = self.runner.invoke(cli_base.os_fetch_rc)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_env_prepare(self):
+ with mock.patch.object(self._env, 'prepare') as mock_method:
+ result = self.runner.invoke(cli_base.env_prepare)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_env_show(self):
+ with mock.patch.object(self._env, 'show') as mock_method:
+ result = self.runner.invoke(cli_base.env_show)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_env_status(self):
+ with mock.patch.object(self._env, 'status') as mock_method:
+ result = self.runner.invoke(cli_base.env_status)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_testcase_list(self):
+ with mock.patch.object(self._testcase, 'list') as mock_method:
+ result = self.runner.invoke(cli_base.testcase_list)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_testcase_show(self):
+ with mock.patch.object(self._testcase, 'show') as mock_method:
+ result = self.runner.invoke(cli_base.testcase_show, ['testname'])
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_testcase_run(self):
+ with mock.patch.object(self._testcase, 'run') as mock_method:
+ result = self.runner.invoke(cli_base.testcase_run,
+ ['testname', '--noclean'])
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_tier_list(self):
+ with mock.patch.object(self._tier, 'list') as mock_method:
+ result = self.runner.invoke(cli_base.tier_list)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_tier_show(self):
+ with mock.patch.object(self._tier, 'show') as mock_method:
+ result = self.runner.invoke(cli_base.tier_show, ['tiername'])
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_tier_gettests(self):
+ with mock.patch.object(self._tier, 'gettests') as mock_method:
+ result = self.runner.invoke(cli_base.tier_gettests, ['tiername'])
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_tier_run(self):
+ with mock.patch.object(self._tier, 'run') as mock_method:
+ result = self.runner.invoke(cli_base.tier_run,
+ ['tiername', '--noclean'])
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/core/test_testcase_base.py b/functest/tests/unit/core/test_testcase_base.py
index b7c81d87c..8df524b0f 100644
--- a/functest/tests/unit/core/test_testcase_base.py
+++ b/functest/tests/unit/core/test_testcase_base.py
@@ -9,8 +9,11 @@
import logging
import mock
+import os
import unittest
+mock.patch('logging.FileHandler').start() # noqa
+
from functest.core import testcase_base
@@ -31,11 +34,12 @@ class TestcaseBaseTesting(unittest.TestCase):
self.assertEqual(self.test.run(),
testcase_base.TestcaseBase.EX_RUN_ERROR)
+ @mock.patch.dict(os.environ, {})
@mock.patch('functest.utils.functest_utils.push_results_to_db',
return_value=False)
def _test_missing_attribute(self, mock_function):
- self.assertEqual(self.test.push_to_db(),
- testcase_base.TestcaseBase.EX_PUSH_TO_DB_ERROR)
+ self.assertEqual(self.test.publish_report(),
+ testcase_base.TestcaseBase.EX_PUBLISH_RESULT_FAILED)
mock_function.assert_not_called()
def test_missing_case_name(self):
@@ -68,7 +72,7 @@ class TestcaseBaseTesting(unittest.TestCase):
return_value=False)
def test_push_to_db_failed(self, mock_function):
self.assertEqual(self.test.push_to_db(),
- testcase_base.TestcaseBase.EX_PUSH_TO_DB_ERROR)
+ testcase_base.TestcaseBase.EX_PUBLISH_RESULT_FAILED)
mock_function.assert_called_once_with(
self.test.project, self.test.case_name, self.test.start_time,
self.test.stop_time, self.test.criteria, self.test.details)
diff --git a/functest/tests/unit/core/test_vnf_base.py b/functest/tests/unit/core/test_vnf_base.py
new file mode 100644
index 000000000..e27f2164b
--- /dev/null
+++ b/functest/tests/unit/core/test_vnf_base.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2016 Orange 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
+
+import logging
+import unittest
+
+from functest.core import vnf_base
+
+
+class VnfBaseTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.test = vnf_base.VnfOnBoardingBase(project='functest',
+ case='aaa')
+ self.test.project = "functest"
+ self.test.case_name = "aaa"
+ self.test.start_time = "1"
+ self.test.stop_time = "5"
+ self.test.criteria = ""
+ self.test.details = {"orchestrator": {"status": "PASS",
+ "result": "",
+ "duration": 20},
+ "vnf": {"status": "PASS",
+ "result": "",
+ "duration": 15},
+ "test_vnf": {"status": "FAIL",
+ "result": "",
+ "duration": 5}}
+
+ def test_deploy_vnf_unimplemented(self):
+ with self.assertRaises(Exception) as context:
+ self.test.deploy_vnf()
+ self.assertTrue('VNF not deployed' in context.exception)
+
+ def test_test_vnf_unimplemented(self):
+ with self.assertRaises(Exception) as context:
+ self.test.test_vnf()()
+ self.assertTrue('VNF not tested' in context.exception)
+
+ def test_parse_results(self):
+ self.assertNotEqual(self.test.parse_results(), 0)
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/odl/test_odl.py b/functest/tests/unit/odl/test_odl.py
index d8c7f84ec..59ab2c654 100644
--- a/functest/tests/unit/odl/test_odl.py
+++ b/functest/tests/unit/odl/test_odl.py
@@ -11,12 +11,15 @@ import errno
import logging
import mock
import os
+import StringIO
import unittest
from keystoneauth1.exceptions import auth_plugins
-from robot.errors import RobotError
+from robot.errors import DataError, RobotError
from robot.result import testcase
+from robot.utils.robottime import timestamp_to_secs
+mock.patch('logging.FileHandler').start() # noqa
from functest.core import testcase_base
from functest.opnfv_tests.sdn.odl import odl
@@ -44,6 +47,17 @@ class ODLTesting(unittest.TestCase):
os.environ["OS_PASSWORD"] = self._os_password
os.environ["OS_TENANT_NAME"] = self._os_tenantname
self.test = odl.ODLTests()
+ self.defaultargs = {'odlusername': self._odl_username,
+ 'odlpassword': self._odl_password,
+ 'keystoneip': self._keystone_ip,
+ 'neutronip': self._keystone_ip,
+ 'osusername': self._os_username,
+ 'ostenantname': self._os_tenantname,
+ 'ospassword': self._os_password,
+ 'odlip': self._keystone_ip,
+ 'odlwebport': self._odl_webport,
+ 'odlrestconfport': self._odl_restconfport,
+ 'pushtodb': False}
def test_empty_visitor(self):
visitor = odl.ODLResultVisitor()
@@ -72,14 +86,65 @@ class ODLTesting(unittest.TestCase):
visitor.visit_test(test)
self.assertEqual(visitor.get_data(), [data])
+ @mock.patch('robot.api.ExecutionResult', side_effect=DataError)
+ def test_parse_results_raises_exceptions(self, *args):
+ with self.assertRaises(DataError):
+ self.test.parse_results()
+
+ def test_parse_results(self, *args):
+ config = {'name': 'dummy', 'starttime': '20161216 16:00:00.000',
+ 'endtime': '20161216 16:00:01.000', 'status': 'PASS'}
+ suite = mock.Mock()
+ suite.configure_mock(**config)
+ with mock.patch('robot.api.ExecutionResult',
+ return_value=mock.Mock(suite=suite)):
+ self.test.parse_results()
+ self.assertEqual(self.test.criteria, config['status'])
+ self.assertEqual(self.test.start_time,
+ timestamp_to_secs(config['starttime']))
+ self.assertEqual(self.test.stop_time,
+ timestamp_to_secs(config['endtime']))
+ self.assertEqual(self.test.details,
+ {'description': config['name'], 'tests': []})
+
@mock.patch('fileinput.input', side_effect=Exception())
def test_set_robotframework_vars_failed(self, *args):
self.assertFalse(self.test.set_robotframework_vars())
@mock.patch('fileinput.input', return_value=[])
- def test_set_robotframework_vars(self, args):
+ def test_set_robotframework_vars_empty(self, args):
self.assertTrue(self.test.set_robotframework_vars())
+ @mock.patch('sys.stdout', new_callable=StringIO.StringIO)
+ def _test_set_robotframework_vars(self, msg1, msg2, *args):
+ line = mock.MagicMock()
+ line.__iter__.return_value = [msg1]
+ with mock.patch('fileinput.input', return_value=line) as mock_method:
+ self.assertTrue(self.test.set_robotframework_vars())
+ mock_method.assert_called_once_with(
+ os.path.join(odl.ODLTests.odl_test_repo,
+ 'csit/variables/Variables.py'), inplace=True)
+ self.assertEqual(args[0].getvalue(), "{}\n".format(msg2))
+
+ def test_set_robotframework_vars_auth_default(self):
+ self._test_set_robotframework_vars("AUTH = []",
+ "AUTH = [u'admin', u'admin']")
+
+ def test_set_robotframework_vars_auth1(self):
+ self._test_set_robotframework_vars("AUTH1 = []", "AUTH1 = []")
+
+ @mock.patch('sys.stdout', new_callable=StringIO.StringIO)
+ def test_set_robotframework_vars_auth_foo(self, *args):
+ line = mock.MagicMock()
+ line.__iter__.return_value = ["AUTH = []"]
+ with mock.patch('fileinput.input', return_value=line) as mock_method:
+ self.assertTrue(self.test.set_robotframework_vars('foo', 'bar'))
+ mock_method.assert_called_once_with(
+ os.path.join(odl.ODLTests.odl_test_repo,
+ 'csit/variables/Variables.py'), inplace=True)
+ self.assertEqual(args[0].getvalue(),
+ "AUTH = [u'{}', u'{}']\n".format('foo', 'bar'))
+
@classmethod
def _fake_url_for(cls, service_type='identity', **kwargs):
if service_type == 'identity':
@@ -194,6 +259,8 @@ class ODLTesting(unittest.TestCase):
def test_main_robot_run_failed(self, *args):
with mock.patch.object(self.test, 'set_robotframework_vars',
return_value=True), \
+ mock.patch.object(odl, 'open', mock.mock_open(),
+ create=True), \
self.assertRaises(RobotError):
self._test_main(testcase_base.TestcaseBase.EX_RUN_ERROR, *args)
@@ -202,6 +269,8 @@ class ODLTesting(unittest.TestCase):
def test_main_parse_results_failed(self, *args):
with mock.patch.object(self.test, 'set_robotframework_vars',
return_value=True), \
+ mock.patch.object(odl, 'open', mock.mock_open(),
+ create=True), \
mock.patch.object(self.test, 'parse_results',
side_effect=RobotError):
self._test_main(testcase_base.TestcaseBase.EX_RUN_ERROR, *args)
@@ -222,6 +291,8 @@ class ODLTesting(unittest.TestCase):
def test_main(self, *args):
with mock.patch.object(self.test, 'set_robotframework_vars',
return_value=True), \
+ mock.patch.object(odl, 'open', mock.mock_open(),
+ create=True), \
mock.patch.object(self.test, 'parse_results'):
self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
@@ -231,6 +302,8 @@ class ODLTesting(unittest.TestCase):
def test_main_makedirs_oserror17(self, *args):
with mock.patch.object(self.test, 'set_robotframework_vars',
return_value=True), \
+ mock.patch.object(odl, 'open', mock.mock_open(),
+ create=True), \
mock.patch.object(self.test, 'parse_results'):
self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
@@ -240,6 +313,8 @@ class ODLTesting(unittest.TestCase):
def test_main_testcases_in_failure(self, *args):
with mock.patch.object(self.test, 'set_robotframework_vars',
return_value=True), \
+ mock.patch.object(odl, 'open', mock.mock_open(),
+ create=True), \
mock.patch.object(self.test, 'parse_results'):
self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
@@ -249,6 +324,8 @@ class ODLTesting(unittest.TestCase):
def test_main_remove_oserror(self, *args):
with mock.patch.object(self.test, 'set_robotframework_vars',
return_value=True), \
+ mock.patch.object(odl, 'open', mock.mock_open(),
+ create=True), \
mock.patch.object(self.test, 'parse_results'):
self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
@@ -260,7 +337,8 @@ class ODLTesting(unittest.TestCase):
testcase_base.TestcaseBase.EX_RUN_ERROR)
def _test_run(self, status=testcase_base.TestcaseBase.EX_OK,
- exception=None, odlip="127.0.0.3", odlwebport="8080"):
+ exception=None, odlip="127.0.0.3", odlwebport="8080",
+ odlrestconfport="8181"):
with mock.patch('functest.utils.openstack_utils.get_endpoint',
side_effect=self._fake_url_for):
if exception:
@@ -271,7 +349,7 @@ class ODLTesting(unittest.TestCase):
self.test.main.assert_called_once_with(
keystoneip=self._keystone_ip, neutronip=self._neutron_ip,
odlip=odlip, odlpassword=self._odl_password,
- odlrestconfport=self._odl_restconfport,
+ odlrestconfport=odlrestconfport,
odlusername=self._odl_username, odlwebport=odlwebport,
ospassword=self._os_password, ostenantname=self._os_tenantname,
osusername=self._os_username)
@@ -333,7 +411,8 @@ class ODLTesting(unittest.TestCase):
os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
os.environ["INSTALLER_TYPE"] = "apex"
self._test_run(testcase_base.TestcaseBase.EX_OK,
- odlip=self._sdn_controller_ip, odlwebport='8181')
+ odlip=self._sdn_controller_ip, odlwebport='8081',
+ odlrestconfport='8081')
def test_run_joid_missing_sdn_controller(self):
with mock.patch('functest.utils.openstack_utils.get_endpoint',
@@ -353,6 +432,77 @@ class ODLTesting(unittest.TestCase):
self._test_run(testcase_base.TestcaseBase.EX_OK,
odlip=self._neutron_ip, odlwebport='8181')
+ def test_argparser_default(self):
+ parser = odl.ODLParser()
+ self.assertEqual(parser.parse_args(), self.defaultargs)
+
+ def test_argparser_basic(self):
+ self.defaultargs['neutronip'] = self._neutron_ip
+ self.defaultargs['odlip'] = self._sdn_controller_ip
+ parser = odl.ODLParser()
+ self.assertEqual(parser.parse_args(
+ ["--neutronip={}".format(self._neutron_ip),
+ "--odlip={}".format(self._sdn_controller_ip)
+ ]), self.defaultargs)
+
+ @mock.patch('sys.stderr', new_callable=StringIO.StringIO)
+ def test_argparser_fail(self, *args):
+ self.defaultargs['foo'] = 'bar'
+ parser = odl.ODLParser()
+ with self.assertRaises(SystemExit):
+ parser.parse_args(["--foo=bar"])
+
+ def _test_argparser(self, arg, value):
+ self.defaultargs[arg] = value
+ parser = odl.ODLParser()
+ self.assertEqual(parser.parse_args(["--{}={}".format(arg, value)]),
+ self.defaultargs)
+
+ def test_argparser_odlusername(self):
+ self._test_argparser('odlusername', 'foo')
+
+ def test_argparser_odlpassword(self):
+ self._test_argparser('odlpassword', 'foo')
+
+ def test_argparser_keystoneip(self):
+ self._test_argparser('keystoneip', '127.0.0.4')
+
+ def test_argparser_neutronip(self):
+ self._test_argparser('neutronip', '127.0.0.4')
+
+ def test_argparser_osusername(self):
+ self._test_argparser('osusername', 'foo')
+
+ def test_argparser_ostenantname(self):
+ self._test_argparser('ostenantname', 'foo')
+
+ def test_argparser_ospassword(self):
+ self._test_argparser('ospassword', 'foo')
+
+ def test_argparser_odlip(self):
+ self._test_argparser('odlip', '127.0.0.4')
+
+ def test_argparser_odlwebport(self):
+ self._test_argparser('odlwebport', '80')
+
+ def test_argparser_odlrestconfport(self):
+ self._test_argparser('odlrestconfport', '80')
+
+ def test_argparser_pushtodb(self):
+ self.defaultargs['pushtodb'] = True
+ parser = odl.ODLParser()
+ self.assertEqual(parser.parse_args(["--{}".format('pushtodb')]),
+ self.defaultargs)
+
+ def test_argparser_multiple_args(self):
+ self.defaultargs['neutronip'] = self._neutron_ip
+ self.defaultargs['odlip'] = self._sdn_controller_ip
+ parser = odl.ODLParser()
+ self.assertEqual(parser.parse_args(
+ ["--neutronip={}".format(self._neutron_ip),
+ "--odlip={}".format(self._sdn_controller_ip)
+ ]), self.defaultargs)
+
if __name__ == "__main__":
unittest.main(verbosity=2)
diff --git a/functest/tests/unit/test_utils.py b/functest/tests/unit/test_utils.py
new file mode 100644
index 000000000..e171db022
--- /dev/null
+++ b/functest/tests/unit/test_utils.py
@@ -0,0 +1,23 @@
+#!/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
+
+import re
+
+
+class RegexMatch(str):
+ def __eq__(self, other):
+ match = re.search(self, other)
+ if match:
+ return True
+ return False
+
+
+class SubstrMatch(str):
+ def __eq__(self, other):
+ if self in other:
+ return True
+ return False
diff --git a/functest/tests/unit/utils/test_functest_utils.py b/functest/tests/unit/utils/test_functest_utils.py
new file mode 100644
index 000000000..c4b566608
--- /dev/null
+++ b/functest/tests/unit/utils/test_functest_utils.py
@@ -0,0 +1,600 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2016 Orange 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
+
+import logging
+import os
+import time
+import unittest
+import urllib2
+
+from git.exc import NoSuchPathError
+import mock
+import requests
+
+from functest.tests.unit import test_utils
+mock.patch('logging.FileHandler').start() # noqa
+from functest.utils import functest_utils
+
+
+class FunctestUtilsTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.url = 'http://www.opnfv.org/'
+ self.timeout = 5
+ self.dest_path = 'test_path'
+ self.repo_path = 'test_repo_path'
+ self.installer = 'test_installer'
+ self.scenario = 'test_scenario'
+ self.build_tag = 'jenkins-functest-fuel-opnfv-jump-2-daily-master-190'
+ self.version = 'master'
+ self.node_name = 'test_node_name'
+ self.project = 'test_project'
+ self.case_name = 'test_case_name'
+ self.status = 'test_status'
+ self.details = 'test_details'
+ self.db_url = 'test_db_url'
+ self.success_rate = 2.0
+ self.criteria = 'test_criteria==2.0'
+ self.start_date = 1482624000
+ self.stop_date = 1482624000
+ self.start_time = time.time()
+ self.stop_time = time.time()
+ self.readline = -1
+ self.test_ip = ['10.1.23.4', '10.1.14.15', '10.1.16.15']
+ self.test_file = 'test_file'
+ self.error_msg = 'test_error_msg'
+ self.cmd = 'test_cmd'
+ self.output_file = 'test_output_file'
+ self.testname = 'testname'
+ self.testcase_dict = {'name': 'testname', 'criteria': self.criteria}
+ self.parameter = 'general.openstack.image_name'
+ self.config_yaml = 'test_config_yaml-'
+ self.file_yaml = {'general': {'openstack': {'image_name':
+ 'test_image_name'}}}
+
+ @mock.patch('urllib2.urlopen',
+ side_effect=urllib2.URLError('no host given'))
+ def test_check_internet_connectivity_failed(self, mock_method):
+ self.assertFalse(functest_utils.check_internet_connectivity())
+ mock_method.assert_called_once_with(self.url, timeout=self.timeout)
+
+ @mock.patch('urllib2.urlopen')
+ def test_check_internet_connectivity_default(self, mock_method):
+ self.assertTrue(functest_utils.check_internet_connectivity())
+ mock_method.assert_called_once_with(self.url, timeout=self.timeout)
+
+ @mock.patch('urllib2.urlopen')
+ def test_check_internet_connectivity_debian(self, mock_method):
+ self.url = "https://www.debian.org/"
+ self.assertTrue(functest_utils.check_internet_connectivity(self.url))
+ mock_method.assert_called_once_with(self.url, timeout=self.timeout)
+
+ @mock.patch('urllib2.urlopen',
+ side_effect=urllib2.URLError('no host given'))
+ def test_download_url_failed(self, mock_url):
+ self.assertFalse(functest_utils.download_url(self.url, self.dest_path))
+
+ @mock.patch('urllib2.urlopen')
+ def test_download_url_default(self, mock_url):
+ with mock.patch("__builtin__.open", mock.mock_open()) as m, \
+ mock.patch('functest.utils.functest_utils.shutil.copyfileobj')\
+ as mock_sh:
+ name = self.url.rsplit('/')[-1]
+ dest = self.dest_path + "/" + name
+ self.assertTrue(functest_utils.download_url(self.url,
+ self.dest_path))
+ m.assert_called_once_with(dest, 'wb')
+ self.assertTrue(mock_sh.called)
+
+ def test_get_git_branch(self):
+ with mock.patch('functest.utils.functest_utils.Repo') as mock_repo:
+ mock_obj2 = mock.Mock()
+ attrs = {'name': 'test_branch'}
+ mock_obj2.configure_mock(**attrs)
+
+ mock_obj = mock.Mock()
+ attrs = {'active_branch': mock_obj2}
+ mock_obj.configure_mock(**attrs)
+
+ mock_repo.return_value = mock_obj
+ self.assertEqual(functest_utils.get_git_branch(self.repo_path),
+ 'test_branch')
+
+ @mock.patch('functest.utils.functest_utils.Repo',
+ side_effect=NoSuchPathError)
+ def test_get_git_branch_failed(self, mock_repo):
+ self.assertRaises(NoSuchPathError,
+ lambda: functest_utils.get_git_branch(self.repo_path
+ ))
+
+ @mock.patch('functest.utils.functest_utils.logger.error')
+ def test_get_installer_type_failed(self, mock_logger_error):
+ with mock.patch.dict(os.environ,
+ {},
+ clear=True):
+ self.assertEqual(functest_utils.get_installer_type(),
+ "Unknown_installer")
+ mock_logger_error.assert_called_once_with("Impossible to retrieve"
+ " the installer type")
+
+ def test_get_installer_type_default(self):
+ with mock.patch.dict(os.environ,
+ {'INSTALLER_TYPE': 'test_installer'},
+ clear=True):
+ self.assertEqual(functest_utils.get_installer_type(),
+ self.installer)
+
+ @mock.patch('functest.utils.functest_utils.logger.error')
+ def test_get_scenario_failed(self, mock_logger_error):
+ with mock.patch.dict(os.environ,
+ {},
+ clear=True):
+ self.assertEqual(functest_utils.get_scenario(),
+ "Unknown_scenario")
+ mock_logger_error.assert_called_once_with("Impossible to retrieve"
+ " the scenario")
+
+ def test_get_scenario_default(self):
+ with mock.patch.dict(os.environ,
+ {'DEPLOY_SCENARIO': 'test_scenario'},
+ clear=True):
+ self.assertEqual(functest_utils.get_scenario(),
+ self.scenario)
+
+ @mock.patch('functest.utils.functest_utils.get_build_tag')
+ def test_get_version_default(self, mock_get_build_tag):
+ mock_get_build_tag.return_value = self.build_tag
+ self.assertEqual(functest_utils.get_version(), self.version)
+
+ @mock.patch('functest.utils.functest_utils.get_build_tag')
+ def test_get_version_unknown(self, mock_get_build_tag):
+ mock_get_build_tag.return_value = "unknown_build_tag"
+ self.assertEqual(functest_utils.get_version(), "unknown")
+
+ @mock.patch('functest.utils.functest_utils.logger.error')
+ def test_get_pod_name_failed(self, mock_logger_error):
+ with mock.patch.dict(os.environ,
+ {},
+ clear=True):
+ self.assertEqual(functest_utils.get_pod_name(),
+ "unknown-pod")
+ mock_logger_error.assert_called_once_with("Unable to retrieve "
+ "the POD name from "
+ "environment. Using "
+ "pod name 'unknown-pod'")
+
+ def test_get_pod_name_default(self):
+ with mock.patch.dict(os.environ,
+ {'NODE_NAME': 'test_node_name'},
+ clear=True):
+ self.assertEqual(functest_utils.get_pod_name(),
+ self.node_name)
+
+ @mock.patch('functest.utils.functest_utils.logger.error')
+ def test_get_build_tag_failed(self, mock_logger_error):
+ with mock.patch.dict(os.environ,
+ {},
+ clear=True):
+ self.assertEqual(functest_utils.get_build_tag(),
+ "unknown_build_tag")
+ mock_logger_error.assert_called_once_with("Impossible to retrieve"
+ " the build tag")
+
+ def test_get_build_tag_default(self):
+ with mock.patch.dict(os.environ,
+ {'BUILD_TAG': self.build_tag},
+ clear=True):
+ self.assertEqual(functest_utils.get_build_tag(),
+ self.build_tag)
+
+ @mock.patch('functest.utils.functest_utils.get_functest_config')
+ def test_get_db_url(self, mock_get_functest_config):
+ mock_get_functest_config.return_value = self.db_url
+ self.assertEqual(functest_utils.get_db_url(), self.db_url)
+ mock_get_functest_config.assert_called_once_with('results.test_db_url')
+
+ @mock.patch('functest.utils.functest_utils.logger.info')
+ def test_logger_test_results(self, mock_logger_info):
+ with mock.patch('functest.utils.functest_utils.get_pod_name',
+ return_value=self.node_name), \
+ mock.patch('functest.utils.functest_utils.get_scenario',
+ return_value=self.scenario), \
+ mock.patch('functest.utils.functest_utils.get_version',
+ return_value=self.version), \
+ mock.patch('functest.utils.functest_utils.get_build_tag',
+ return_value=self.build_tag), \
+ mock.patch('functest.utils.functest_utils.get_db_url',
+ return_value=self.db_url):
+ functest_utils.logger_test_results(self.project, self.case_name,
+ self.status, self.details)
+ mock_logger_info.assert_called_once_with(
+ "\n"
+ "****************************************\n"
+ "\t %(p)s/%(n)s results \n\n"
+ "****************************************\n"
+ "DB:\t%(db)s\n"
+ "pod:\t%(pod)s\n"
+ "version:\t%(v)s\n"
+ "scenario:\t%(s)s\n"
+ "status:\t%(c)s\n"
+ "build tag:\t%(b)s\n"
+ "details:\t%(d)s\n"
+ % {'p': self.project,
+ 'n': self.case_name,
+ 'db': self.db_url,
+ 'pod': self.node_name,
+ 'v': self.version,
+ 's': self.scenario,
+ 'c': self.status,
+ 'b': self.build_tag,
+ 'd': self.details})
+
+ def _get_env_dict(self, var):
+ dic = {'INSTALLER_TYPE': self.installer,
+ 'DEPLOY_SCENARIO': self.scenario,
+ 'NODE_NAME': self.node_name,
+ 'BUILD_TAG': self.build_tag}
+ dic.pop(var, None)
+ return dic
+
+ def _test_push_results_to_db_missing_env(self, env_var):
+ dic = self._get_env_dict(env_var)
+ with mock.patch('functest.utils.functest_utils.get_db_url',
+ return_value=self.db_url), \
+ mock.patch.dict(os.environ,
+ dic,
+ clear=True), \
+ mock.patch('functest.utils.functest_utils.logger.error') \
+ as mock_logger_error:
+ functest_utils.push_results_to_db(self.project, self.case_name,
+ self.start_date, self.stop_date,
+ self.criteria, self.details)
+ mock_logger_error.assert_called_once_with("Please set env var: " +
+ str("\'" + env_var +
+ "\'"))
+
+ def test_push_results_to_db_missing_installer(self):
+ self._test_push_results_to_db_missing_env('INSTALLER_TYPE')
+
+ def test_push_results_to_db_missing_scenario(self):
+ self._test_push_results_to_db_missing_env('DEPLOY_SCENARIO')
+
+ def test_push_results_to_db_missing_nodename(self):
+ self._test_push_results_to_db_missing_env('NODE_NAME')
+
+ def test_push_results_to_db_missing_buildtag(self):
+ self._test_push_results_to_db_missing_env('BUILD_TAG')
+
+ def test_push_results_to_db_incorrect_buildtag(self):
+ dic = self._get_env_dict(None)
+ dic['BUILD_TAG'] = 'incorrect_build_tag'
+ with mock.patch('functest.utils.functest_utils.get_db_url',
+ return_value=self.db_url), \
+ mock.patch.dict(os.environ,
+ dic,
+ clear=True), \
+ mock.patch('functest.utils.functest_utils.logger.error') \
+ as mock_logger_error:
+ self.assertFalse(functest_utils.
+ push_results_to_db(self.project, self.case_name,
+ self.start_date,
+ self.stop_date,
+ self.criteria, self.details))
+ mock_logger_error.assert_called_once_with("Please fix BUILD_TAG"
+ " env var: incorrect_"
+ "build_tag")
+
+ def test_push_results_to_db_request_post_failed(self):
+ dic = self._get_env_dict(None)
+ with mock.patch('functest.utils.functest_utils.get_db_url',
+ return_value=self.db_url), \
+ mock.patch.dict(os.environ,
+ dic,
+ clear=True), \
+ mock.patch('functest.utils.functest_utils.logger.error') \
+ as mock_logger_error, \
+ mock.patch('functest.utils.functest_utils.requests.post',
+ side_effect=requests.RequestException):
+ self.assertFalse(functest_utils.
+ push_results_to_db(self.project, self.case_name,
+ self.start_date,
+ self.stop_date,
+ self.criteria, self.details))
+ mock_logger_error.assert_called_once_with(test_utils.
+ RegexMatch("Pushing "
+ "Result to"
+ " DB"
+ "(\S+\s*) "
+ "failed:"))
+
+ def test_push_results_to_db_request_post_exception(self):
+ dic = self._get_env_dict(None)
+ with mock.patch('functest.utils.functest_utils.get_db_url',
+ return_value=self.db_url), \
+ mock.patch.dict(os.environ,
+ dic,
+ clear=True), \
+ mock.patch('functest.utils.functest_utils.logger.error') \
+ as mock_logger_error, \
+ mock.patch('functest.utils.functest_utils.requests.post',
+ side_effect=Exception):
+ self.assertFalse(functest_utils.
+ push_results_to_db(self.project, self.case_name,
+ self.start_date,
+ self.stop_date,
+ self.criteria, self.details))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_push_results_to_db_default(self):
+ dic = self._get_env_dict(None)
+ with mock.patch('functest.utils.functest_utils.get_db_url',
+ return_value=self.db_url), \
+ mock.patch.dict(os.environ,
+ dic,
+ clear=True), \
+ mock.patch('functest.utils.functest_utils.requests.post'):
+ self.assertTrue(functest_utils.
+ push_results_to_db(self.project, self.case_name,
+ self.start_date,
+ self.stop_date,
+ self.criteria, self.details))
+ readline = 0
+ test_ip = ['10.1.23.4', '10.1.14.15', '10.1.16.15']
+
+ @staticmethod
+ def readline_side():
+ if FunctestUtilsTesting.readline == \
+ len(FunctestUtilsTesting.test_ip) - 1:
+ return False
+ FunctestUtilsTesting.readline += 1
+ return FunctestUtilsTesting.test_ip[FunctestUtilsTesting.readline]
+
+ # TODO: get_resolvconf_ns
+ @mock.patch('functest.utils.functest_utils.dns.resolver.Resolver')
+ def test_get_resolvconf_ns_default(self, mock_dns_resolve):
+ attrs = {'query.return_value': ["test"]}
+ mock_dns_resolve.configure_mock(**attrs)
+
+ m = mock.Mock()
+ attrs = {'readline.side_effect': self.readline_side}
+ m.configure_mock(**attrs)
+
+ with mock.patch("__builtin__.open") as mo:
+ mo.return_value = m
+ self.assertEqual(functest_utils.get_resolvconf_ns(),
+ self.test_ip[1:])
+
+ def _get_environ(self, var):
+ if var == 'INSTALLER_TYPE':
+ return self.installer
+ elif var == 'DEPLOY_SCENARIO':
+ return self.scenario
+ return var
+
+ def test_get_ci_envvars_default(self):
+ with mock.patch('os.environ.get',
+ side_effect=self._get_environ):
+ dic = {"installer": self.installer,
+ "scenario": self.scenario}
+ self.assertDictEqual(functest_utils.get_ci_envvars(), dic)
+
+ def cmd_readline(self):
+ return 'test_value\n'
+
+ @mock.patch('functest.utils.functest_utils.logger.error')
+ @mock.patch('functest.utils.functest_utils.logger.info')
+ def test_execute_command_args_present_with_error(self, mock_logger_info,
+ mock_logger_error):
+ with mock.patch('functest.utils.functest_utils.subprocess.Popen') \
+ as mock_subproc_open, \
+ mock.patch('__builtin__.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)
+ self.assertEqual(resp, 1)
+ msg_exec = ("Executing command: '%s'" % self.cmd)
+ mock_logger_info.assert_called_once_with(msg_exec)
+ mopen.assert_called_once_with(self.output_file, "w")
+ mock_logger_error.assert_called_once_with(self.error_msg)
+
+ @mock.patch('functest.utils.functest_utils.logger.info')
+ def test_execute_command_args_present_with_success(self, mock_logger_info,
+ ):
+ with mock.patch('functest.utils.functest_utils.subprocess.Popen') \
+ as mock_subproc_open, \
+ mock.patch('__builtin__.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)
+ self.assertEqual(resp, 0)
+ msg_exec = ("Executing command: '%s'" % self.cmd)
+ mock_logger_info.assert_called_once_with(msg_exec)
+ mopen.assert_called_once_with(self.output_file, "w")
+
+ @mock.patch('functest.utils.functest_utils.logger.info')
+ def test_execute_command_args_missing_with_success(self, mock_logger_info,
+ ):
+ 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)
+ self.assertEqual(resp, 0)
+
+ @mock.patch('functest.utils.functest_utils.logger.error')
+ def test_execute_command_args_missing_with_error(self, mock_logger_error,
+ ):
+ 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)
+ self.assertEqual(resp, 1)
+
+ def _get_functest_config(self, var):
+ return var
+
+ @mock.patch('functest.utils.functest_utils.logger.error')
+ def test_get_dict_by_test(self, mock_logger_error):
+ with mock.patch('__builtin__.open', mock.mock_open()), \
+ mock.patch('functest.utils.functest_utils.yaml.safe_load') \
+ as mock_yaml, \
+ mock.patch('functest.utils.functest_utils.get_testcases_'
+ 'file_dir'):
+ mock_obj = mock.Mock()
+ attrs = {'get.return_value': [{'testcases': [self.testcase_dict]}]}
+ mock_obj.configure_mock(**attrs)
+
+ mock_yaml.return_value = mock_obj
+
+ self.assertDictEqual(functest_utils.
+ get_dict_by_test(self.testname),
+ self.testcase_dict)
+
+ @mock.patch('functest.utils.functest_utils.get_dict_by_test')
+ def test_get_criteria_by_test_default(self, mock_get_dict_by_test):
+ mock_get_dict_by_test.return_value = self.testcase_dict
+ self.assertEqual(functest_utils.get_criteria_by_test(self.testname),
+ self.criteria)
+
+ @mock.patch('functest.utils.functest_utils.get_dict_by_test')
+ def test_get_criteria_by_test_failed(self, mock_get_dict_by_test):
+ mock_get_dict_by_test.return_value = None
+ self.assertIsNone(functest_utils.get_criteria_by_test(self.testname))
+
+ def test_get_parameter_from_yaml_failed(self):
+ self.file_yaml['general'] = None
+ with mock.patch('__builtin__.open', mock.mock_open()), \
+ mock.patch('functest.utils.functest_utils.yaml.safe_load') \
+ as mock_yaml, \
+ self.assertRaises(ValueError) as excep:
+ 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)
+
+ def test_get_parameter_from_yaml_default(self):
+ with mock.patch('__builtin__.open', mock.mock_open()), \
+ mock.patch('functest.utils.functest_utils.yaml.safe_load') \
+ as mock_yaml:
+ mock_yaml.return_value = self.file_yaml
+ self.assertEqual(functest_utils.
+ get_parameter_from_yaml(self.parameter,
+ self.test_file),
+ 'test_image_name')
+
+ @mock.patch('functest.utils.functest_utils.get_parameter_from_yaml')
+ def test_get_functest_config_default(self, mock_get_parameter_from_yaml):
+ with mock.patch.dict(os.environ,
+ {'CONFIG_FUNCTEST_YAML': self.config_yaml}):
+ functest_utils.get_functest_config(self.parameter)
+ mock_get_parameter_from_yaml. \
+ assert_called_once_with(self.parameter,
+ self.config_yaml)
+
+ def test_check_success_rate_default(self):
+ with mock.patch('functest.utils.functest_utils.get_criteria_by_test') \
+ as mock_criteria:
+ mock_criteria.return_value = self.criteria
+ resp = functest_utils.check_success_rate(self.case_name,
+ self.success_rate)
+ self.assertEqual(resp, 'PASS')
+
+ def test_check_success_rate_failed(self):
+ with mock.patch('functest.utils.functest_utils.get_criteria_by_test') \
+ as mock_criteria:
+ mock_criteria.return_value = self.criteria
+ resp = functest_utils.check_success_rate(self.case_name,
+ 3.0)
+ self.assertEqual(resp, 'FAIL')
+
+ # TODO: merge_dicts
+
+ def test_get_testcases_file_dir(self):
+ resp = functest_utils.get_testcases_file_dir()
+ self.assertEqual(resp,
+ "/home/opnfv/repos/functest/"
+ "functest/ci/testcases.yaml")
+
+ def test_get_functest_yaml(self):
+ with mock.patch('__builtin__.open', mock.mock_open()), \
+ mock.patch('functest.utils.functest_utils.yaml.safe_load') \
+ as mock_yaml:
+ mock_yaml.return_value = self.file_yaml
+ resp = functest_utils.get_functest_yaml()
+ self.assertEqual(resp, self.file_yaml)
+
+ @mock.patch('functest.utils.functest_utils.logger.info')
+ def test_print_separator(self, mock_logger_info):
+ functest_utils.print_separator()
+ mock_logger_info.assert_called_once_with("======================="
+ "=======================")
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/utils/test_openstack_clean.py b/functest/tests/unit/utils/test_openstack_clean.py
new file mode 100644
index 000000000..28eab4f8a
--- /dev/null
+++ b/functest/tests/unit/utils/test_openstack_clean.py
@@ -0,0 +1,671 @@
+#!/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
+
+import logging
+import mock
+import unittest
+
+from functest.utils import openstack_clean
+from functest.tests.unit import test_utils
+
+
+class OSCleanTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def _get_instance(self, key):
+ mock_obj = mock.Mock()
+ attrs = {'id': 'id' + str(key), 'name': 'name' + str(key),
+ 'ip': 'ip' + str(key)}
+ mock_obj.configure_mock(**attrs)
+ return mock_obj
+
+ def setUp(self):
+ self.client = mock.Mock()
+ self.test_list = [self._get_instance(1), self._get_instance(2)]
+ self.update_list = {'id1': 'name1', 'id2': 'name2'}
+ self.remove_list = {'id3': 'name3', 'id4': 'name4'}
+ self.test_dict_list = [{'id': 'id1', 'name': 'name1', 'ip': 'ip1',
+ 'router:external': False,
+ 'external_gateway_info': None},
+ {'id': 'id2', 'name': 'name2', 'ip': 'ip2',
+ 'router:external': False,
+ 'external_gateway_info': None}]
+ self.routers = [mock.Mock()]
+ self.ports = [mock.Mock()]
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_separator(self, mock_logger_debug):
+ openstack_clean.separator()
+ mock_logger_debug.assert_called_once_with("-----------------"
+ "-----------------"
+ "---------")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_instances(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_instances', return_value=self.test_list):
+ openstack_clean.remove_instances(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing Nova instances...")
+ mock_logger_debug.assert_any_call(" > this is a default "
+ "instance and will "
+ "NOT be deleted.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_instances_missing_instances(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_instances', return_value=[]):
+ openstack_clean.remove_instances(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing Nova instances...")
+ mock_logger_debug.assert_any_call("No instances found.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_instances_delete_success(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_instances', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_instance', return_value=True):
+ openstack_clean.remove_instances(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Nova instances...")
+ mock_logger_debug.assert_any_call(" > Request sent.")
+ mock_logger_debug.assert_any_call(test_utils.RegexMatch("Removing"
+ " instance"
+ " '\s*\S+'"
+ " ..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_instances_delete_failed(self, mock_logger_debug,
+ mock_logger_error):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_instances', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_instance', return_value=False):
+ openstack_clean.remove_instances(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Nova instances...")
+ mock_logger_error.assert_any_call(test_utils.
+ RegexMatch("There has been a "
+ "problem removing "
+ "the instance \s*\S+"
+ "..."))
+ mock_logger_debug.assert_any_call(test_utils.RegexMatch("Removing"
+ " instance"
+ " '\s*\S+'"
+ " ..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_images(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_images', return_value=self.test_list):
+ openstack_clean.remove_images(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing Glance images...")
+ mock_logger_debug.assert_any_call(" > this is a default "
+ "image and will "
+ "NOT be deleted.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_images_missing_images(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_images', return_value=[]):
+ openstack_clean.remove_images(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing Glance images...")
+ mock_logger_debug.assert_any_call("No images found.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_images_delete_success(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_images', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_glance_image', return_value=True):
+ openstack_clean.remove_images(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Glance images...")
+ mock_logger_debug.assert_any_call(" > Done!")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Removing image "
+ "\s*\S+,"
+ " ID=\s*\S+ ..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_images_delete_failed(self, mock_logger_debug,
+ mock_logger_error):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_images', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_glance_image', return_value=False):
+ openstack_clean.remove_images(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Glance images...")
+ mock_logger_error.assert_any_call(test_utils.
+ RegexMatch("There has been a "
+ "problem removing the"
+ "image \s*\S+..."))
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Removing image "
+ "\s*\S+,"
+ " ID=\s*\S+ ..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_volumes(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_volumes', return_value=self.test_list):
+ openstack_clean.remove_volumes(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing Cinder volumes...")
+ mock_logger_debug.assert_any_call(" > this is a default "
+ "volume and will "
+ "NOT be deleted.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_volumes_missing_volumes(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_volumes', return_value=[]):
+ openstack_clean.remove_volumes(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing Cinder volumes...")
+ mock_logger_debug.assert_any_call("No volumes found.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_volumes_delete_success(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_volumes', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_volume', return_value=True):
+ openstack_clean.remove_volumes(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Cinder volumes...")
+ mock_logger_debug.assert_any_call(" > Done!")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Removing cinder "
+ "volume \s*\S+ ..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_volumes_delete_failed(self, mock_logger_debug,
+ mock_logger_error):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_volumes', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_volume', return_value=False):
+ openstack_clean.remove_volumes(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Cinder volumes...")
+ mock_logger_error.assert_any_call(test_utils.
+ RegexMatch("There has been a "
+ "problem removing "
+ "the "
+ "volume \s*\S+..."))
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Removing cinder "
+ "volume \s*\S+ ..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_floatingips(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_floating_ips', return_value=self.test_list):
+ openstack_clean.remove_floatingips(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing floating IPs...")
+ mock_logger_debug.assert_any_call(" > this is a default "
+ "floating IP and will "
+ "NOT be deleted.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_floatingips_missing_floatingips(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_floating_ips', return_value=[]):
+ openstack_clean.remove_floatingips(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing floating IPs...")
+ mock_logger_debug.assert_any_call("No floating IPs found.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_floatingips_delete_success(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_floating_ips', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_volume', return_value=True):
+ openstack_clean.remove_floatingips(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing floating IPs...")
+ mock_logger_debug.assert_any_call(" > Done!")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Removing floating "
+ "IP \s*\S+ ..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_floatingips_delete_failed(self, mock_logger_debug,
+ mock_logger_error):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_floating_ips', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_floating_ip', return_value=False):
+ openstack_clean.remove_floatingips(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing floating IPs...")
+ mock_logger_error.assert_any_call(test_utils.
+ RegexMatch("There has been a "
+ "problem removing "
+ "the floating IP "
+ "\s*\S+..."))
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Removing floating "
+ "IP \s*\S+ ..."))
+
+ @mock.patch('functest.utils.openstack_clean.remove_routers')
+ @mock.patch('functest.utils.openstack_clean.remove_ports')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_networks(self, mock_logger_debug,
+ mock_remove_ports,
+ mock_remove_routers):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_network_list',
+ return_value=self.test_dict_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_port_list', return_value=self.ports), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_router_list', return_value=self.routers):
+ openstack_clean.remove_networks(self.client, self.update_list,
+ self.update_list)
+ mock_logger_debug.assert_any_call("Removing Neutron objects")
+ mock_logger_debug.assert_any_call(" > this is a default "
+ "network and will "
+ "NOT be deleted.")
+ mock_remove_ports.assert_called_once_with(self.client, self.ports,
+ [])
+ mock_remove_routers.assert_called_once_with(self.client,
+ self.routers,
+ self.update_list)
+
+ @mock.patch('functest.utils.openstack_clean.remove_routers')
+ @mock.patch('functest.utils.openstack_clean.remove_ports')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_networks_missing_networks(self, mock_logger_debug,
+ mock_remove_ports,
+ mock_remove_routers):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_network_list', return_value=None), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_port_list', return_value=self.ports), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_router_list', return_value=self.routers):
+ openstack_clean.remove_networks(self.client, self.update_list,
+ self.update_list)
+ mock_logger_debug.assert_any_call("Removing Neutron objects")
+ mock_logger_debug.assert_any_call("There are no networks in the"
+ " deployment. ")
+ mock_remove_ports.assert_called_once_with(self.client, self.ports,
+ [])
+ mock_remove_routers.assert_called_once_with(self.client,
+ self.routers,
+ self.update_list)
+
+ @mock.patch('functest.utils.openstack_clean.remove_routers')
+ @mock.patch('functest.utils.openstack_clean.remove_ports')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_networks_delete_success(self, mock_logger_debug,
+ mock_remove_ports,
+ mock_remove_routers):
+
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_network_list',
+ return_value=self.test_dict_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_neutron_net', return_value=True), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_port_list', return_value=self.ports), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_router_list', return_value=self.routers):
+ openstack_clean.remove_networks(self.client, self.remove_list,
+ self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Neutron objects")
+ mock_logger_debug.assert_any_call(" > this network will be "
+ "deleted.")
+ mock_logger_debug.assert_any_call(" > Done!")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Removing network "
+ "\s*\S+ ..."))
+ mock_remove_ports.assert_called_once_with(self.client, self.ports,
+ ['id1', 'id2'])
+ mock_remove_routers.assert_called_once_with(self.client,
+ self.routers,
+ self.remove_list)
+
+ @mock.patch('functest.utils.openstack_clean.remove_routers')
+ @mock.patch('functest.utils.openstack_clean.remove_ports')
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_networks_delete_failed(self, mock_logger_debug,
+ mock_logger_error,
+ mock_remove_ports,
+ mock_remove_routers):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_network_list',
+ return_value=self.test_dict_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_neutron_net', return_value=False), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_port_list', return_value=self.ports), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_router_list', return_value=self.routers):
+ openstack_clean.remove_networks(self.client, self.remove_list,
+ self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Neutron objects")
+ mock_logger_error.assert_any_call(test_utils.
+ RegexMatch("There has been a"
+ " problem removing"
+ " the network \s*\S+"
+ "..."))
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Removing network "
+ "\s*\S+ ..."))
+ mock_remove_ports.assert_called_once_with(self.client, self.ports,
+ ['id1', 'id2'])
+ mock_remove_routers.assert_called_once_with(self.client,
+ self.routers,
+ self.remove_list)
+
+ # TODO: ports
+ @mock.patch('functest.utils.openstack_clean.os_utils.update_neutron_port')
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_force_remove_port(self, mock_logger_debug,
+ mock_logger_error,
+ mock_update_neutron_port):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_neutron_port',
+ return_value=True):
+ openstack_clean.force_remove_port(self.client, 'id')
+ mock_logger_debug.assert_any_call(" > Done!")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Clearing device_"
+ "owner for port "
+ "\s*\S+ ..."))
+
+ @mock.patch('functest.utils.openstack_clean.os_utils.update_neutron_port')
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_force_remove_port_failed(self, mock_logger_debug,
+ mock_logger_error,
+ mock_update_neutron_port):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_neutron_port',
+ return_value=False):
+ openstack_clean.force_remove_port(self.client, 'id')
+ mock_logger_error.assert_any_call("There has been a "
+ "problem removing "
+ "the port id...")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Clearing device_"
+ "owner for port "
+ "\s*\S+ ..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_routers_missing_routers(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_neutron_router',
+ return_value=True):
+ openstack_clean.remove_routers(self.client, self.test_dict_list,
+ self.remove_list)
+ mock_logger_debug.assert_any_call("Router is not connected"
+ " to anything."
+ "Ready to remove...")
+ mock_logger_debug.assert_any_call(" > Done!")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Removing router "
+ "\s*\S+(\s*\S+) ..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_routers_failed(self, mock_logger_debug,
+ mock_logger_error):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_neutron_router',
+ return_value=False):
+ openstack_clean.remove_routers(self.client, self.test_dict_list,
+ self.remove_list)
+ mock_logger_debug.assert_any_call("Router is not connected"
+ " to anything."
+ "Ready to remove...")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Removing router "
+ "\s*\S+(\s*\S+) ..."))
+ mock_logger_error.assert_any_call(test_utils.
+ RegexMatch("There has been "
+ "a problem"
+ " removing the "
+ "router \s*\S+("
+ "\s*\S+)..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_missing_external_gateway(self, mock_logger_debug,
+ mock_logger_error):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_neutron_router',
+ return_value=False), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.remove_gateway_router',
+ return_value=False):
+ self.test_dict_list[0]['external_gateway_info'] = mock.Mock()
+ openstack_clean.remove_routers(self.client, self.test_dict_list,
+ self.remove_list)
+ mock_logger_debug.assert_any_call("Router has gateway to external"
+ " network.Removing link...")
+ mock_logger_error.assert_any_call("There has been a problem "
+ "removing the gateway...")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch("Removing router "
+ "\s*\S+(\s*\S+) ..."))
+ mock_logger_error.assert_any_call(test_utils.
+ RegexMatch("There has been "
+ "a problem"
+ " removing the "
+ "router \s*\S+("
+ "\s*\S+)..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def remove_security_groups(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_security_groups',
+ return_value=self.test_dict_list):
+ openstack_clean.remove_security_groups(self.client,
+ self.update_list)
+ mock_logger_debug.assert_any_call("Removing Security groups...")
+ mock_logger_debug.assert_any_call(" > this is a default "
+ "security group and will NOT "
+ "be deleted.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_security_groups_missing_sec_group(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_security_groups', return_value=[]):
+ openstack_clean.remove_security_groups(self.client,
+ self.update_list)
+ mock_logger_debug.assert_any_call("Removing Security groups...")
+ mock_logger_debug.assert_any_call("No security groups found.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_security_groups_delete_success(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_security_groups',
+ return_value=self.test_dict_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_security_group', return_value=True):
+ openstack_clean.remove_security_groups(self.client,
+ self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Security groups...")
+ mock_logger_debug.assert_any_call(" > Done!")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch(" Removing \s*\S+"
+ "..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_security_groups_delete_failed(self, mock_logger_debug,
+ mock_logger_error):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_security_groups',
+ return_value=self.test_dict_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_security_group', return_value=False):
+ openstack_clean.remove_security_groups(self.client,
+ self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Security groups...")
+ mock_logger_error.assert_any_call(test_utils.
+ RegexMatch("There has been a "
+ "problem removing "
+ "the security group"
+ " \s*\S+..."))
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch(" Removing \s*\S+"
+ "..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_users(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_users', return_value=self.test_list):
+ openstack_clean.remove_users(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing Users...")
+ mock_logger_debug.assert_any_call(" > this is a default "
+ "user and will "
+ "NOT be deleted.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_users_missing_users(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_users', return_value=None):
+ openstack_clean.remove_users(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing Users...")
+ mock_logger_debug.assert_any_call("There are no users in"
+ " the deployment. ")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_users_delete_success(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_users', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_user', return_value=True):
+ openstack_clean.remove_users(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Users...")
+ mock_logger_debug.assert_any_call(" > Done!")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch(" Removing "
+ "\s*\S+..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_users_delete_failed(self, mock_logger_debug,
+ mock_logger_error):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_users', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_user', return_value=False):
+ openstack_clean.remove_users(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Users...")
+ mock_logger_error.assert_any_call(test_utils.
+ RegexMatch("There has been a "
+ "problem removing "
+ "the user \s*\S+"
+ "..."))
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch(" Removing "
+ "\s*\S+..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_tenants(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_tenants', return_value=self.test_list):
+ openstack_clean.remove_tenants(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing Tenants...")
+ mock_logger_debug.assert_any_call(" > this is a default"
+ " tenant and will "
+ "NOT be deleted.")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_tenants_missing_tenants(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_tenants', return_value=None):
+ openstack_clean.remove_tenants(self.client, self.update_list)
+ mock_logger_debug.assert_any_call("Removing Tenants...")
+ mock_logger_debug.assert_any_call("There are no tenants in"
+ " the deployment. ")
+
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_tenants_delete_success(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_tenants', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_tenant', return_value=True):
+ openstack_clean.remove_tenants(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Tenants...")
+ mock_logger_debug.assert_any_call(" > Done!")
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch(" Removing "
+ "\s*\S+..."))
+
+ @mock.patch('functest.utils.openstack_clean.logger.error')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_remove_tenants_delete_failed(self, mock_logger_debug,
+ mock_logger_error):
+ with mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_tenants', return_value=self.test_list), \
+ mock.patch('functest.utils.openstack_clean.os_utils'
+ '.delete_tenant', return_value=False):
+ openstack_clean.remove_tenants(self.client, self.remove_list)
+ mock_logger_debug.assert_any_call("Removing Tenants...")
+ mock_logger_error.assert_any_call(test_utils.
+ RegexMatch("There has been a "
+ "problem removing "
+ "the tenant \s*\S+"
+ "..."))
+ mock_logger_debug.assert_any_call(test_utils.
+ RegexMatch(" Removing "
+ "\s*\S+..."))
+
+ @mock.patch('functest.utils.openstack_clean.os_utils.get_cinder_client')
+ @mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_keystone_client')
+ @mock.patch('functest.utils.openstack_clean.os_utils'
+ '.get_neutron_client')
+ @mock.patch('functest.utils.openstack_clean.os_utils.get_nova_client')
+ @mock.patch('functest.utils.openstack_clean.os_utils.check_credentials',
+ return_value=True)
+ @mock.patch('functest.utils.openstack_clean.logger.info')
+ @mock.patch('functest.utils.openstack_clean.logger.debug')
+ def test_main_default(self, mock_logger_debug, mock_logger_info,
+ mock_creds, mock_nova, mock_neutron,
+ mock_keystone, mock_cinder):
+
+ with mock.patch('functest.utils.openstack_clean.remove_instances') \
+ as mock_remove_instances, \
+ mock.patch('functest.utils.openstack_clean.remove_images') \
+ as mock_remove_images, \
+ mock.patch('functest.utils.openstack_clean.remove_volumes') \
+ as mock_remove_volumes, \
+ mock.patch('functest.utils.openstack_clean.remove_floatingips') \
+ as mock_remove_floatingips, \
+ mock.patch('functest.utils.openstack_clean.remove_networks') \
+ as mock_remove_networks, \
+ mock.patch('functest.utils.openstack_clean.'
+ 'remove_security_groups') \
+ as mock_remove_security_groups, \
+ mock.patch('functest.utils.openstack_clean.remove_users') \
+ as mock_remove_users, \
+ mock.patch('functest.utils.openstack_clean.remove_tenants') \
+ as mock_remove_tenants, \
+ mock.patch('functest.utils.openstack_clean.yaml.safe_load',
+ return_value=mock.Mock()), \
+ mock.patch('__builtin__.open', mock.mock_open()) as m:
+ openstack_clean.main()
+ self.assertTrue(mock_remove_instances)
+ self.assertTrue(mock_remove_images)
+ self.assertTrue(mock_remove_volumes)
+ self.assertTrue(mock_remove_floatingips)
+ self.assertTrue(mock_remove_networks)
+ self.assertTrue(mock_remove_security_groups)
+ self.assertTrue(mock_remove_users)
+ self.assertTrue(mock_remove_tenants)
+ m.assert_called_once_with(openstack_clean.OS_SNAPSHOT_FILE)
+ mock_logger_info.assert_called_once_with("Cleaning OpenStack "
+ "resources...")
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/utils/test_openstack_snapshot.py b/functest/tests/unit/utils/test_openstack_snapshot.py
new file mode 100644
index 000000000..52744db1c
--- /dev/null
+++ b/functest/tests/unit/utils/test_openstack_snapshot.py
@@ -0,0 +1,235 @@
+#!/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
+
+import logging
+import mock
+import unittest
+
+from functest.utils import openstack_snapshot
+
+
+class OSTackerTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def _get_instance(self, key):
+ mock_obj = mock.Mock()
+ attrs = {'id': 'id' + str(key), 'name': 'name' + str(key),
+ 'ip': 'ip' + str(key)}
+ mock_obj.configure_mock(**attrs)
+ return mock_obj
+
+ def setUp(self):
+ self.client = mock.Mock()
+ self.test_list = [self._get_instance(1), self._get_instance(2)]
+ self.update_list = {'id1': 'name1', 'id2': 'name2'}
+ self.update_floatingips = {'id1': 'ip1', 'id2': 'ip2'}
+ self.test_dict_list = [{'id': 'id1', 'name': 'name1', 'ip': 'ip1'},
+ {'id': 'id2', 'name': 'name2', 'ip': 'ip2'}]
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.info')
+ def test_separator(self, mock_logger_info):
+ openstack_snapshot.separator()
+ mock_logger_info.assert_called_once_with("-----------------"
+ "-----------------"
+ "---------")
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_instances(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_instances', return_value=self.test_list):
+ resp = openstack_snapshot.get_instances(self.client)
+ mock_logger_debug.assert_called_once_with("Getting instances...")
+ self.assertDictEqual(resp, {'instances': self.update_list})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_instances_missing_instances(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_instances', return_value=[]):
+ resp = openstack_snapshot.get_instances(self.client)
+ mock_logger_debug.assert_called_once_with("Getting instances...")
+ self.assertDictEqual(resp, {'instances': {}})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_images(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_images', return_value=self.test_list):
+ resp = openstack_snapshot.get_images(self.client)
+ mock_logger_debug.assert_called_once_with("Getting images...")
+ self.assertDictEqual(resp, {'images': self.update_list})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_images_missing_images(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_images', return_value=[]):
+ resp = openstack_snapshot.get_images(self.client)
+ mock_logger_debug.assert_called_once_with("Getting images...")
+ self.assertDictEqual(resp, {'images': {}})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_volumes(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_volumes', return_value=self.test_list):
+ resp = openstack_snapshot.get_volumes(self.client)
+ mock_logger_debug.assert_called_once_with("Getting volumes...")
+ self.assertDictEqual(resp, {'volumes': self.update_list})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_volumes_missing_volumes(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_volumes', return_value=[]):
+ resp = openstack_snapshot.get_volumes(self.client)
+ mock_logger_debug.assert_called_once_with("Getting volumes...")
+ self.assertDictEqual(resp, {'volumes': {}})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_networks(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_network_list', return_value=self.test_dict_list):
+ resp = openstack_snapshot.get_networks(self.client)
+ mock_logger_debug.assert_called_once_with("Getting networks")
+ self.assertDictEqual(resp, {'networks': self.update_list})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_networks_missing_networks(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_network_list', return_value=[]):
+ resp = openstack_snapshot.get_networks(self.client)
+ mock_logger_debug.assert_called_once_with("Getting networks")
+ self.assertDictEqual(resp, {'networks': {}})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_routers(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_router_list', return_value=self.test_dict_list):
+ resp = openstack_snapshot.get_routers(self.client)
+ mock_logger_debug.assert_called_once_with("Getting routers")
+ self.assertDictEqual(resp, {'routers': self.update_list})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_routers_missing_routers(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_router_list', return_value=[]):
+ resp = openstack_snapshot.get_routers(self.client)
+ mock_logger_debug.assert_called_once_with("Getting routers")
+ self.assertDictEqual(resp, {'routers': {}})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_secgroups(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_security_groups',
+ return_value=self.test_dict_list):
+ resp = openstack_snapshot.get_security_groups(self.client)
+ mock_logger_debug.assert_called_once_with("Getting Security "
+ "groups...")
+ self.assertDictEqual(resp, {'secgroups': self.update_list})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_secgroups_missing_secgroups(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_security_groups', return_value=[]):
+ resp = openstack_snapshot.get_security_groups(self.client)
+ mock_logger_debug.assert_called_once_with("Getting Security "
+ "groups...")
+ self.assertDictEqual(resp, {'secgroups': {}})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_floatingips(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_floating_ips', return_value=self.test_list):
+ resp = openstack_snapshot.get_floatinips(self.client)
+ mock_logger_debug.assert_called_once_with("Getting Floating "
+ "IPs...")
+ self.assertDictEqual(resp, {'floatingips':
+ self.update_floatingips})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_floatingips_missing_floatingips(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_floating_ips', return_value=[]):
+ resp = openstack_snapshot.get_floatinips(self.client)
+ mock_logger_debug.assert_called_once_with("Getting Floating "
+ "IPs...")
+ self.assertDictEqual(resp, {'floatingips': {}})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_users(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_users', return_value=self.test_list):
+ resp = openstack_snapshot.get_users(self.client)
+ mock_logger_debug.assert_called_once_with("Getting users...")
+ self.assertDictEqual(resp, {'users': self.update_list})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_users_missing_users(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_users', return_value=[]):
+ resp = openstack_snapshot.get_users(self.client)
+ mock_logger_debug.assert_called_once_with("Getting users...")
+ self.assertDictEqual(resp, {'users': {}})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_tenants(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_tenants', return_value=self.test_list):
+ resp = openstack_snapshot.get_tenants(self.client)
+ mock_logger_debug.assert_called_once_with("Getting tenants...")
+ self.assertDictEqual(resp, {'tenants': self.update_list})
+
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_get_tenants_missing_tenants(self, mock_logger_debug):
+ with mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_tenants', return_value=[]):
+ resp = openstack_snapshot.get_tenants(self.client)
+ mock_logger_debug.assert_called_once_with("Getting tenants...")
+ self.assertDictEqual(resp, {'tenants': {}})
+
+ @mock.patch('functest.utils.openstack_snapshot.os_utils.get_cinder_client')
+ @mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_keystone_client')
+ @mock.patch('functest.utils.openstack_snapshot.os_utils'
+ '.get_neutron_client')
+ @mock.patch('functest.utils.openstack_snapshot.os_utils.get_nova_client')
+ @mock.patch('functest.utils.openstack_snapshot.os_utils.check_credentials')
+ @mock.patch('functest.utils.openstack_snapshot.logger.info')
+ @mock.patch('functest.utils.openstack_snapshot.logger.debug')
+ def test_main_default(self, mock_logger_debug, mock_logger_info,
+ mock_creds, mock_nova, mock_neutron,
+ mock_keystone, mock_cinder):
+ with mock.patch('functest.utils.openstack_snapshot.get_instances',
+ return_value=self.update_list), \
+ mock.patch('functest.utils.openstack_snapshot.get_images',
+ return_value=self.update_list), \
+ mock.patch('functest.utils.openstack_snapshot.get_images',
+ return_value=self.update_list), \
+ mock.patch('functest.utils.openstack_snapshot.get_volumes',
+ return_value=self.update_list), \
+ mock.patch('functest.utils.openstack_snapshot.get_networks',
+ return_value=self.update_list), \
+ mock.patch('functest.utils.openstack_snapshot.get_routers',
+ return_value=self.update_list), \
+ mock.patch('functest.utils.openstack_snapshot.get_security_groups',
+ return_value=self.update_list), \
+ mock.patch('functest.utils.openstack_snapshot.get_floatinips',
+ return_value=self.update_floatingips), \
+ mock.patch('functest.utils.openstack_snapshot.get_users',
+ return_value=self.update_list), \
+ mock.patch('functest.utils.openstack_snapshot.get_tenants',
+ return_value=self.update_list), \
+ mock.patch('__builtin__.open', mock.mock_open()) as m:
+ openstack_snapshot.main()
+ mock_logger_info.assert_called_once_with("Generating OpenStack "
+ "snapshot...")
+ m.assert_called_once_with(openstack_snapshot.OS_SNAPSHOT_FILE,
+ 'w+')
+ mock_logger_debug.assert_any_call("NOTE: These objects will "
+ "NOT be deleted after " +
+ "running the test.")
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/utils/test_openstack_tacker.py b/functest/tests/unit/utils/test_openstack_tacker.py
new file mode 100644
index 000000000..a8330c0ed
--- /dev/null
+++ b/functest/tests/unit/utils/test_openstack_tacker.py
@@ -0,0 +1,455 @@
+#!/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
+
+import logging
+import mock
+import unittest
+
+from functest.utils import openstack_tacker
+from functest.tests.unit import test_utils
+
+
+class OSTackerTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.tacker_client = mock.Mock()
+ self.getresponse = {'vnfds': [{'id': 'test_id'}],
+ 'vnfs': [{'id': 'test_id'}],
+ 'sfcs': [{'id': 'test_id'}]}
+ self.vnfdlist = {'vnfds': [{'id': 'test_vnfd1'}, {'id': 'test_vnfd2'}]}
+ self.vnflist = {'vnfs': [{'id': 'test_vnf1'}, {'id': 'test_vnf2'}]}
+ self.sfclist = {'sfcs': [{'id': 'test_sfc1'}, {'id': 'test_sfc2'}]}
+ self.sfc_classifierlist = {'sfc_classifiers': [{'id': 'test_sfc_cl1'},
+ {'id': 'test_sfc_cl2'}]}
+
+ self.createvnfd = {"vnfd": {"attributes": {"vnfd": 'vnfd_body'}}}
+ self.createvnf = {"vnf": {"attributes": {"vnf": 'vnf_body'}}}
+ self.createsfc = {"sfc": {"attributes": {"sfc": 'sfc_body'}}}
+ self.createsfc_clf = {"sfc_classifier": {"attributes":
+ {"sfc_clf": 'sfc_clf_body'}}}
+
+ self.resource_type = 'vnfd'
+ self.resource_name = 'resource_name'
+ self.tosca_file = 'test_tosca_file'
+ self.vnfd = 'test_vnfd'
+ self.vnf = 'test_vnf'
+ self.sfc = 'test_sfc'
+ self.sfc_clf = 'test_sfc_clf'
+
+ def _get_creds(self):
+ cred_dict = {
+ 'OS_USERNAME': 'username',
+ 'OS_PASSWORD': 'password',
+ 'OS_AUTH_URL': 'auth_url',
+ 'OS_TENANT_NAME': 'tenant_name',
+ 'OS_USER_DOMAIN_NAME': 'user_domain_name',
+ 'OS_PROJECT_DOMAIN_NAME': 'project_domain_name',
+ 'OS_PROJECT_NAME': 'project_name',
+ 'OS_ENDPOINT_TYPE': 'endpoint_type',
+ 'OS_REGION_NAME': 'region_name'
+ }
+ return cred_dict
+
+ def test_get_id_from_name(self):
+ with mock.patch.object(self.tacker_client, 'get',
+ return_value=self.getresponse):
+ resp = openstack_tacker.get_id_from_name(self.tacker_client,
+ self.resource_type,
+ self.resource_name)
+ self.assertEqual(resp, 'test_id')
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_get_id_from_name_exception(self, mock_logger_error):
+ with mock.patch.object(self.tacker_client, 'get',
+ side_effect=Exception):
+ resp = openstack_tacker.get_id_from_name(self.tacker_client,
+ self.resource_type,
+ self.resource_name)
+ self.assertIsNone(resp)
+ mock_logger_error.assert_called_once_with(test_utils.
+ SubstrMatch("Error [get"
+ "_id_from_"
+ "name(tacker"
+ "_client"
+ ", resource_"
+ "type, "
+ "resource_"
+ "name)]:"))
+
+ @mock.patch('functest.utils.openstack_tacker.get_id_from_name')
+ def test_get_vnfd_id(self, mock_get_id_from_name):
+ openstack_tacker.get_vnfd_id(self.tacker_client, self.resource_name)
+ mock_get_id_from_name.assert_called_once_with(self.tacker_client,
+ 'vnfd',
+ self.resource_name)
+
+ @mock.patch('functest.utils.openstack_tacker.get_id_from_name')
+ def test_get_vnf_id(self, mock_get_id_from_name):
+ openstack_tacker.get_vnf_id(self.tacker_client, self.resource_name)
+ mock_get_id_from_name.assert_called_once_with(self.tacker_client,
+ 'vnf',
+ self.resource_name)
+
+ @mock.patch('functest.utils.openstack_tacker.get_id_from_name')
+ def test_get_sfc_id(self, mock_get_id_from_name):
+ openstack_tacker.get_sfc_id(self.tacker_client, self.resource_name)
+ mock_get_id_from_name.assert_called_once_with(self.tacker_client,
+ 'sfc',
+ self.resource_name)
+
+ @mock.patch('functest.utils.openstack_tacker.get_id_from_name')
+ def test_get_sfc_classifier_id(self, mock_get_id_from_name):
+ openstack_tacker.get_sfc_classifier_id(self.tacker_client,
+ self.resource_name)
+ mock_get_id_from_name.assert_called_once_with(self.tacker_client,
+ 'sfc-classifier',
+ self.resource_name)
+
+ def test_list_vnfds(self):
+ with mock.patch.object(self.tacker_client, 'list_vnfds',
+ return_value=self.vnfdlist):
+ resp = openstack_tacker.list_vnfds(self.tacker_client,
+ verbose=False)
+ self.assertEqual(resp, ['test_vnfd1', 'test_vnfd2'])
+
+ def test_list_vnfds_verbose(self):
+ with mock.patch.object(self.tacker_client, 'list_vnfds',
+ return_value=self.vnfdlist):
+ resp = openstack_tacker.list_vnfds(self.tacker_client,
+ verbose=True)
+ self.assertEqual(resp, self.vnfdlist)
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_list_vnfds_exception(self, mock_logger_error):
+ with mock.patch.object(self.tacker_client, 'list_vnfds',
+ side_effect=Exception):
+ resp = openstack_tacker.list_vnfds(self.tacker_client,
+ verbose=False)
+ mock_logger_error.assert_called_once_with(test_utils.
+ SubstrMatch("Error"
+ " [list"
+ "_vnfds("
+ "tacker_"
+ "client)]:"))
+ self.assertIsNone(resp)
+
+ def test_create_vnfd_missing_file(self):
+ with mock.patch.object(self.tacker_client, 'create_vnfd',
+ return_value=self.createvnfd):
+ resp = openstack_tacker.create_vnfd(self.tacker_client,
+ tosca_file=None)
+ self.assertEqual(resp, self.createvnfd)
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_create_vnfd_default(self, mock_logger_error):
+ with mock.patch.object(self.tacker_client, 'create_vnfd',
+ return_value=self.createvnfd), \
+ mock.patch('__builtin__.open', mock.mock_open(read_data='1')) \
+ as m:
+ resp = openstack_tacker.create_vnfd(self.tacker_client,
+ tosca_file=self.tosca_file)
+ m.assert_called_once_with(self.tosca_file)
+ mock_logger_error.assert_called_once_with('1')
+ self.assertEqual(resp, self.createvnfd)
+
+ @mock.patch('functest.utils.openstack_tacker.logger.exception')
+ def test_create_vnfd_exception(self, mock_logger_excep):
+ with mock.patch.object(self.tacker_client, 'create_vnfd',
+ side_effect=Exception):
+ resp = openstack_tacker.create_vnfd(self.tacker_client,
+ tosca_file=self.tosca_file)
+ mock_logger_excep.assert_called_once_with(test_utils.
+ SubstrMatch("Error"
+ " [create"
+ "_vnfd("
+ "tacker_"
+ "client, "
+ "'%s')]"
+ % self.
+ tosca_file))
+ self.assertIsNone(resp)
+
+ def test_delete_vnfd(self):
+ with mock.patch('functest.utils.openstack_tacker.get_vnfd_id',
+ return_value=self.vnfd), \
+ mock.patch.object(self.tacker_client, 'delete_vnfd',
+ return_value=self.vnfd):
+ resp = openstack_tacker.delete_vnfd(self.tacker_client,
+ vnfd_id='vnfd_id',
+ vnfd_name=self.vnfd)
+ self.assertEqual(resp, self.vnfd)
+
+ # TODO: Exception('You need to provide an VNFD'
+ # 'id or name') AssertionError
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_delete_vnfd_exception(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_tacker.get_vnfd_id',
+ return_value=self.vnfd), \
+ mock.patch.object(self.tacker_client, 'delete_vnfd',
+ side_effect=Exception):
+ resp = openstack_tacker.delete_vnfd(self.tacker_client,
+ vnfd_id=None,
+ vnfd_name=None)
+ self.assertIsNone(resp)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_list_vnfs(self):
+ with mock.patch.object(self.tacker_client, 'list_vnfs',
+ return_value=self.vnflist):
+ resp = openstack_tacker.list_vnfs(self.tacker_client,
+ verbose=False)
+ self.assertEqual(resp, ['test_vnf1', 'test_vnf2'])
+
+ def test_list_vnfs_verbose(self):
+ with mock.patch.object(self.tacker_client, 'list_vnfs',
+ return_value=self.vnflist):
+ resp = openstack_tacker.list_vnfs(self.tacker_client,
+ verbose=True)
+ self.assertEqual(resp, self.vnflist)
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_list_vnfs_exception(self, mock_logger_error):
+ with mock.patch.object(self.tacker_client, 'list_vnfs',
+ side_effect=Exception):
+ resp = openstack_tacker.list_vnfs(self.tacker_client,
+ verbose=False)
+ mock_logger_error.assert_called_once_with(test_utils.
+ SubstrMatch("Error"
+ " [list"
+ "_vnfs("
+ "tacker_"
+ "client)]:"))
+ self.assertIsNone(resp)
+
+ def test_create_vnf_default(self):
+ with mock.patch.object(self.tacker_client, 'create_vnf',
+ return_value=self.createvnf), \
+ mock.patch('functest.utils.openstack_tacker.get_vnfd_id',
+ return_value=self.vnf):
+ resp = openstack_tacker.create_vnf(self.tacker_client,
+ vnf_name=self.vnf,
+ vnfd_id='vnfd_id',
+ vnfd_name=self.vnfd)
+ self.assertEqual(resp, self.createvnf)
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_create_vnf_exception(self, mock_logger_error):
+ with mock.patch.object(self.tacker_client, 'create_vnf',
+ side_effect=Exception):
+ resp = openstack_tacker.create_vnf(self.tacker_client,
+ vnf_name=self.vnf,
+ vnfd_id='vnfd_id',
+ vnfd_name=self.vnfd)
+ mock_logger_error.assert_called_once_with(test_utils.
+ SubstrMatch("error"
+ " [create"
+ "_vnf("
+ "tacker_"
+ "client"))
+ self.assertIsNone(resp)
+
+ # TODO: wait_for_vnf
+
+ def test_delete_vnf(self):
+ with mock.patch('functest.utils.openstack_tacker.get_vnf_id',
+ return_value=self.vnf), \
+ mock.patch.object(self.tacker_client, 'delete_vnf',
+ return_value=self.vnf):
+ resp = openstack_tacker.delete_vnf(self.tacker_client,
+ vnf_id='vnf_id',
+ vnf_name=self.vnf)
+ self.assertEqual(resp, self.vnf)
+
+ # TODO: Exception('You need to provide an VNF'
+ # 'classifier id or name') AssertionError
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_delete_vnf_exception(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_tacker.get_vnf_id',
+ return_value=self.vnf), \
+ mock.patch.object(self.tacker_client, 'delete_vnf',
+ side_effect=Exception):
+ resp = openstack_tacker.delete_vnf(self.tacker_client,
+ vnf_id=None,
+ vnf_name=None)
+ self.assertIsNone(resp)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_list_sfcs(self):
+ with mock.patch.object(self.tacker_client, 'list_sfcs',
+ return_value=self.sfclist):
+ resp = openstack_tacker.list_sfcs(self.tacker_client,
+ verbose=False)
+ self.assertEqual(resp, ['test_sfc1', 'test_sfc2'])
+
+ def test_list_sfcs_verbose(self):
+ with mock.patch.object(self.tacker_client, 'list_sfcs',
+ return_value=self.sfclist):
+ resp = openstack_tacker.list_sfcs(self.tacker_client,
+ verbose=True)
+ self.assertEqual(resp, self.sfclist)
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_list_sfcs_exception(self, mock_logger_error):
+ with mock.patch.object(self.tacker_client, 'list_sfcs',
+ side_effect=Exception):
+ resp = openstack_tacker.list_sfcs(self.tacker_client,
+ verbose=False)
+ mock_logger_error.assert_called_once_with(test_utils.
+ SubstrMatch("Error"
+ " [list"
+ "_sfcs("
+ "tacker_"
+ "client)]:"))
+ self.assertIsNone(resp)
+
+ def test_create_sfc_default(self):
+ with mock.patch.object(self.tacker_client, 'create_sfc',
+ return_value=self.createsfc), \
+ mock.patch('functest.utils.openstack_tacker.get_vnf_id',
+ return_value=self.vnf):
+ resp = openstack_tacker.create_sfc(self.tacker_client,
+ sfc_name=self.sfc,
+ chain_vnf_ids=['chain_vnf_id'],
+ chain_vnf_names=[self.vnf])
+ self.assertEqual(resp, self.createsfc)
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_create_sfc_exception(self, mock_logger_error):
+ with mock.patch.object(self.tacker_client, 'create_sfc',
+ side_effect=Exception):
+ resp = openstack_tacker.create_sfc(self.tacker_client,
+ sfc_name=self.sfc,
+ chain_vnf_ids=['chain_vnf_id'],
+ chain_vnf_names=[self.vnf])
+ mock_logger_error.assert_called_once_with(test_utils.
+ SubstrMatch("error"
+ " [create"
+ "_sfc("
+ "tacker_"
+ "client"))
+ self.assertIsNone(resp)
+
+ def test_delete_sfc(self):
+ with mock.patch('functest.utils.openstack_tacker.get_sfc_id',
+ return_value=self.sfc), \
+ mock.patch.object(self.tacker_client, 'delete_sfc',
+ return_value=self.sfc):
+ resp = openstack_tacker.delete_sfc(self.tacker_client,
+ sfc_id='sfc_id',
+ sfc_name=self.sfc)
+ self.assertEqual(resp, self.sfc)
+
+ # TODO: Exception('You need to provide an SFC'
+ # 'id or name') AssertionError
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_delete_sfc_exception(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_tacker.get_sfc_id',
+ return_value=self.sfc), \
+ mock.patch.object(self.tacker_client, 'delete_sfc',
+ side_effect=Exception):
+ resp = openstack_tacker.delete_sfc(self.tacker_client,
+ sfc_id=None,
+ sfc_name=None)
+ self.assertIsNone(resp)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_list_sfc_classifiers(self):
+ with mock.patch.object(self.tacker_client, 'list_sfc_classifiers',
+ return_value=self.sfc_classifierlist):
+ resp = openstack_tacker.list_sfc_classifiers(self.tacker_client,
+ verbose=False)
+ self.assertEqual(resp, ['test_sfc_cl1', 'test_sfc_cl2'])
+
+ def test_list_sfc_classifiers_verbose(self):
+ with mock.patch.object(self.tacker_client, 'list_sfc_classifiers',
+ return_value=self.sfc_classifierlist):
+ resp = openstack_tacker.list_sfc_classifiers(self.tacker_client,
+ verbose=True)
+ self.assertEqual(resp, self.sfc_classifierlist)
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_list_sfc_classifiers_exception(self, mock_logger_error):
+ with mock.patch.object(self.tacker_client, 'list_sfc_classifiers',
+ side_effect=Exception):
+ resp = openstack_tacker.list_sfc_classifiers(self.tacker_client,
+ verbose=False)
+ mock_logger_error.assert_called_once_with(test_utils.
+ SubstrMatch("Error"
+ " [list"
+ "_sfc_cl"
+ "assifiers("
+ "tacker_"
+ "client)]:"))
+ self.assertIsNone(resp)
+
+ def test_create_sfc_classifier_default(self):
+ with mock.patch.object(self.tacker_client, 'create_sfc_classifier',
+ return_value=self.createsfc_clf), \
+ mock.patch('functest.utils.openstack_tacker.get_sfc_id',
+ return_value=self.sfc):
+ cl = self.sfc_clf
+ resp = openstack_tacker.create_sfc_classifier(self.tacker_client,
+ sfc_clf_name=cl,
+ sfc_id='sfc_id',
+ sfc_name=self.sfc)
+ self.assertEqual(resp, self.createsfc_clf)
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_sfc_classifier_exception(self, mock_logger_error):
+ with mock.patch.object(self.tacker_client, 'create_sfc_classifier',
+ side_effect=Exception):
+ cl = self.sfc_clf
+ resp = openstack_tacker.create_sfc_classifier(self.tacker_client,
+ sfc_clf_name=cl,
+ sfc_id='sfc_id',
+ sfc_name=self.sfc)
+ mock_logger_error.assert_called_once_with(test_utils.
+ SubstrMatch("error"
+ " [create"
+ "_sfc_cl"
+ "assifier("
+ "tacker_"
+ "client"))
+ self.assertIsNone(resp)
+
+ def test_delete_sfc_classifier(self):
+ with mock.patch('functest.utils.openstack_tacker.get_sfc_'
+ 'classifier_id',
+ return_value=self.sfc_clf), \
+ mock.patch.object(self.tacker_client, 'delete_sfc_classifier',
+ return_value=self.sfc_clf):
+ cl = self.sfc_clf
+ resp = openstack_tacker.delete_sfc_classifier(self.tacker_client,
+ sfc_clf_id='sfc_id',
+ sfc_clf_name=cl)
+ self.assertEqual(resp, cl)
+
+ # TODO: Exception('You need to provide an SFC'
+ # 'classifier id or name') AssertionError
+
+ @mock.patch('functest.utils.openstack_tacker.logger.error')
+ def test_delete_sfc_classifier_exception(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_tacker.get_sfc_'
+ 'classifier_id',
+ return_value=self.sfc_clf), \
+ mock.patch.object(self.tacker_client, 'delete_sfc_classifier',
+ side_effect=Exception):
+ cl = self.sfc_clf
+ resp = openstack_tacker.delete_sfc_classifier(self.tacker_client,
+ sfc_clf_id='sfc_id',
+ sfc_clf_name=cl)
+ self.assertIsNone(resp)
+ self.assertTrue(mock_logger_error.called)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/utils/test_openstack_utils.py b/functest/tests/unit/utils/test_openstack_utils.py
new file mode 100644
index 000000000..0f510414b
--- /dev/null
+++ b/functest/tests/unit/utils/test_openstack_utils.py
@@ -0,0 +1,1688 @@
+#!/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
+
+import copy
+import logging
+import unittest
+
+import mock
+
+from functest.utils import openstack_utils
+
+
+class OSUtilsTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def _get_env_cred_dict(self, os_prefix=''):
+ return {'OS_USERNAME': os_prefix + 'username',
+ 'OS_PASSWORD': os_prefix + 'password',
+ 'OS_AUTH_URL': os_prefix + 'auth_url',
+ 'OS_TENANT_NAME': os_prefix + 'tenant_name',
+ 'OS_USER_DOMAIN_NAME': os_prefix + 'user_domain_name',
+ 'OS_PROJECT_DOMAIN_NAME': os_prefix + 'project_domain_name',
+ 'OS_PROJECT_NAME': os_prefix + 'project_name',
+ 'OS_ENDPOINT_TYPE': os_prefix + 'endpoint_type',
+ 'OS_REGION_NAME': os_prefix + 'region_name'}
+
+ def _get_os_env_vars(self):
+ return {'username': 'test_username', 'password': 'test_password',
+ 'auth_url': 'test_auth_url', 'tenant_name': 'test_tenant_name',
+ 'user_domain_name': 'test_user_domain_name',
+ 'project_domain_name': 'test_project_domain_name',
+ 'project_name': 'test_project_name',
+ 'endpoint_type': 'test_endpoint_type',
+ 'region_name': 'test_region_name'}
+
+ def setUp(self):
+ self.env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD']
+ self.tenant_name = 'test_tenant_name'
+ self.env_cred_dict = self._get_env_cred_dict()
+ self.os_environs = self._get_env_cred_dict(os_prefix='test_')
+ self.os_env_vars = self._get_os_env_vars()
+
+ mock_obj = mock.Mock()
+ attrs = {'name': 'test_flavor',
+ 'id': 'flavor_id',
+ 'ram': 2}
+ mock_obj.configure_mock(**attrs)
+ self.flavor = mock_obj
+
+ mock_obj = mock.Mock()
+ attrs = {'name': 'test_aggregate',
+ 'id': 'aggregate_id',
+ 'hosts': ['host_name']}
+ mock_obj.configure_mock(**attrs)
+ self.aggregate = mock_obj
+
+ mock_obj = mock.Mock()
+ attrs = {'id': 'instance_id',
+ 'name': 'test_instance',
+ 'status': 'ok'}
+ mock_obj.configure_mock(**attrs)
+ self.instance = mock_obj
+
+ mock_obj = mock.Mock()
+ attrs = {'id': 'azone_id',
+ 'zoneName': 'test_azone',
+ 'status': 'ok'}
+ mock_obj.configure_mock(**attrs)
+ self.availability_zone = mock_obj
+
+ mock_obj = mock.Mock()
+ attrs = {'id': 'floating_id',
+ 'zoneName': 'test_floating_ip',
+ 'status': 'ok'}
+ mock_obj.configure_mock(**attrs)
+ self.floating_ip = mock_obj
+
+ mock_obj = mock.Mock()
+ attrs = {'id': 'hypervisor_id',
+ 'hypervisor_hostname': 'test_hostname',
+ 'state': 'up'}
+ mock_obj.configure_mock(**attrs)
+ self.hypervisor = mock_obj
+
+ mock_obj = mock.Mock()
+ attrs = {'id': 'image_id',
+ 'name': 'test_image'}
+ mock_obj.configure_mock(**attrs)
+ self.image = mock_obj
+
+ mock_obj = mock.Mock()
+ self.mock_return = mock_obj
+
+ self.nova_client = mock.Mock()
+ attrs = {'servers.list.return_value': [self.instance],
+ 'servers.get.return_value': self.instance,
+ 'servers.find.return_value': self.instance,
+ 'servers.create.return_value': self.instance,
+ 'flavors.list.return_value': [self.flavor],
+ 'flavors.find.return_value': self.flavor,
+ 'flavors.list.return_value': [self.flavor],
+ 'servers.add_floating_ip.return_value': mock.Mock(),
+ 'servers.force_delete.return_value': mock.Mock(),
+ 'aggregates.list.return_value': [self.aggregate],
+ 'aggregates.add_host.return_value': mock.Mock(),
+ 'aggregates.remove_host.return_value': mock.Mock(),
+ 'aggregates.get.return_value': self.aggregate,
+ 'aggregates.delete.return_value': mock.Mock(),
+ 'availability_zones.list.return_value':
+ [self.availability_zone],
+ 'floating_ips.list.return_value': [self.floating_ip],
+ 'floating_ips.delete.return_value': mock.Mock(),
+ 'hypervisors.list.return_value': [self.hypervisor],
+ 'create.return_value': mock.Mock(),
+ 'add_security_group.return_value': mock.Mock(),
+ 'images.list.return_value': [self.image],
+ 'images.delete.return_value': mock.Mock(),
+ }
+ self.nova_client.configure_mock(**attrs)
+
+ self.glance_client = mock.Mock()
+ attrs = {'images.list.return_value': [self.image],
+ 'images.create.return_value': self.image,
+ 'images.upload.return_value': mock.Mock()}
+ self.glance_client.configure_mock(**attrs)
+
+ mock_obj = mock.Mock()
+ attrs = {'id': 'volume_id',
+ 'name': 'test_volume'}
+ mock_obj.configure_mock(**attrs)
+ self.volume = mock_obj
+
+ mock_obj = mock.Mock()
+ attrs = {'id': 'volume_type_id',
+ 'name': 'test_volume_type',
+ 'is_public': True}
+ mock_obj.configure_mock(**attrs)
+ self.volume_types = [mock_obj]
+
+ mock_obj = mock.Mock()
+ attrs = {'id': 'volume_type_id',
+ 'name': 'test_volume_type',
+ 'is_public': False}
+ mock_obj.configure_mock(**attrs)
+ self.volume_types.append(mock_obj)
+
+ self.cinder_client = mock.Mock()
+ attrs = {'volumes.list.return_value': [self.volume],
+ 'volume_types.list.return_value': self.volume_types,
+ 'volume_types.create.return_value': self.volume_types[0],
+ 'volume_types.delete.return_value': mock.Mock(),
+ 'quotas.update.return_value': mock.Mock(),
+ 'volumes.detach.return_value': mock.Mock(),
+ 'volumes.force_delete.return_value': mock.Mock(),
+ 'volumes.delete.return_value': mock.Mock()
+ }
+ self.cinder_client.configure_mock(**attrs)
+
+ mock_obj = mock.Mock()
+ attrs = {'id': 'tenant_id',
+ 'name': 'test_tenant'}
+ mock_obj.configure_mock(**attrs)
+ self.tenant = mock_obj
+
+ mock_obj = mock.Mock()
+ attrs = {'id': 'user_id',
+ 'name': 'test_user'}
+ mock_obj.configure_mock(**attrs)
+ self.user = mock_obj
+
+ mock_obj = mock.Mock()
+ attrs = {'id': 'role_id',
+ 'name': 'test_role'}
+ mock_obj.configure_mock(**attrs)
+ self.role = mock_obj
+
+ self.keystone_client = mock.Mock()
+ attrs = {'projects.list.return_value': [self.tenant],
+ 'tenants.list.return_value': [self.tenant],
+ 'users.list.return_value': [self.user],
+ 'roles.list.return_value': [self.role],
+ 'projects.create.return_value': self.tenant,
+ 'tenants.create.return_value': self.tenant,
+ 'users.create.return_value': self.user,
+ 'roles.grant.return_value': mock.Mock(),
+ 'roles.add_user_role.return_value': mock.Mock(),
+ 'projects.delete.return_value': mock.Mock(),
+ 'tenants.delete.return_value': mock.Mock(),
+ 'users.delete.return_value': mock.Mock(),
+ }
+ self.keystone_client.configure_mock(**attrs)
+
+ self.router = {'id': 'router_id',
+ 'name': 'test_router'}
+
+ self.subnet = {'id': 'subnet_id',
+ 'name': 'test_subnet'}
+
+ self.networks = [{'id': 'network_id',
+ 'name': 'test_network',
+ 'router:external': False,
+ 'shared': True,
+ 'subnets': [self.subnet]},
+ {'id': 'network_id1',
+ 'name': 'test_network1',
+ 'router:external': True,
+ 'shared': True,
+ 'subnets': [self.subnet]}]
+
+ self.port = {'id': 'port_id',
+ 'name': 'test_port'}
+
+ self.sec_group = {'id': 'sec_group_id',
+ 'name': 'test_sec_group'}
+
+ self.neutron_floatingip = {'id': 'fip_id',
+ 'floating_ip_address': 'test_ip'}
+ self.neutron_client = mock.Mock()
+ attrs = {'list_networks.return_value': {'networks': self.networks},
+ 'list_routers.return_value': {'routers': [self.router]},
+ 'list_ports.return_value': {'ports': [self.port]},
+ 'list_subnets.return_value': {'subnets': [self.subnet]},
+ 'create_network.return_value': {'network': self.networks[0]},
+ 'create_subnet.return_value': {'subnets': [self.subnet]},
+ 'create_router.return_value': {'router': self.router},
+ 'create_port.return_value': {'port': self.port},
+ 'create_floatingip.return_value': {'floatingip':
+ self.neutron_floatingip},
+ 'update_network.return_value': mock.Mock(),
+ 'update_port.return_value': {'port': self.port},
+ 'add_interface_router.return_value': mock.Mock(),
+ 'add_gateway_router.return_value': mock.Mock(),
+ 'delete_network.return_value': mock.Mock(),
+ 'delete_subnet.return_value': mock.Mock(),
+ 'delete_router.return_value': mock.Mock(),
+ 'delete_port.return_value': mock.Mock(),
+ 'remove_interface_router.return_value': mock.Mock(),
+ 'remove_gateway_router.return_value': mock.Mock(),
+ 'create_bgpvpn.return_value': self.mock_return,
+ 'create_network_association.return_value': self.mock_return,
+ 'create_router_association.return_value': self.mock_return,
+ 'update_bgpvpn.return_value': self.mock_return,
+ 'delete_bgpvpn.return_value': self.mock_return,
+ 'show_bgpvpn.return_value': self.mock_return,
+ 'list_security_groups.return_value': {'security_groups':
+ [self.sec_group]},
+ 'create_security_group_rule.return_value': mock.Mock(),
+ 'create_security_group.return_value': {'security_group':
+ self.sec_group},
+ 'update_quota.return_value': mock.Mock(),
+ 'delete_security_group.return_value': mock.Mock()
+ }
+ self.neutron_client.configure_mock(**attrs)
+
+ self.empty_client = mock.Mock()
+ attrs = {'list_networks.return_value': {'networks': []},
+ 'list_routers.return_value': {'routers': []},
+ 'list_ports.return_value': {'ports': []},
+ 'list_subnets.return_value': {'subnets': []}}
+ self.empty_client.configure_mock(**attrs)
+
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value=None)
+ def test_is_keystone_v3_missing_identity(self, mock_os_getenv):
+ self.assertEqual(openstack_utils.is_keystone_v3(), False)
+
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value='3')
+ def test_is_keystone_v3_default(self, mock_os_getenv):
+ self.assertEqual(openstack_utils.is_keystone_v3(), True)
+
+ @mock.patch('functest.utils.openstack_utils.is_keystone_v3',
+ return_value=False)
+ def test_get_rc_env_vars_missing_identity(self, mock_get_rc_env):
+ exp_resp = self.env_vars
+ exp_resp.extend(['OS_TENANT_NAME'])
+ self.assertEqual(openstack_utils.get_rc_env_vars(), exp_resp)
+
+ @mock.patch('functest.utils.openstack_utils.is_keystone_v3',
+ return_value=True)
+ def test_get_rc_env_vars_default(self, mock_get_rc_env):
+ exp_resp = self.env_vars
+ exp_resp.extend(['OS_PROJECT_NAME',
+ 'OS_USER_DOMAIN_NAME',
+ 'OS_PROJECT_DOMAIN_NAME'])
+ self.assertEqual(openstack_utils.get_rc_env_vars(), exp_resp)
+
+ @mock.patch('functest.utils.openstack_utils.get_rc_env_vars')
+ def test_check_credentials_missing_env(self, mock_get_rc_env):
+ exp_resp = self.env_vars
+ exp_resp.extend(['OS_TENANT_NAME'])
+ mock_get_rc_env.return_value = exp_resp
+ with mock.patch.dict('functest.utils.openstack_utils.os.environ', {},
+ clear=True):
+ self.assertEqual(openstack_utils.check_credentials(), False)
+
+ @mock.patch('functest.utils.openstack_utils.get_rc_env_vars')
+ def test_check_credentials_default(self, mock_get_rc_env):
+ exp_resp = ['OS_TENANT_NAME']
+ mock_get_rc_env.return_value = exp_resp
+ with mock.patch.dict('functest.utils.openstack_utils.os.environ',
+ {'OS_TENANT_NAME': self.tenant_name},
+ clear=True):
+ self.assertEqual(openstack_utils.check_credentials(), True)
+
+ def test_get_env_cred_dict(self):
+ self.assertDictEqual(openstack_utils.get_env_cred_dict(),
+ self.env_cred_dict)
+
+ @mock.patch('functest.utils.openstack_utils.get_rc_env_vars')
+ def test_get_credentials_default(self, mock_get_rc_env):
+ mock_get_rc_env.return_value = self.env_cred_dict.keys()
+ with mock.patch.dict('functest.utils.openstack_utils.os.environ',
+ self.os_environs,
+ clear=True):
+ self.assertDictEqual(openstack_utils.get_credentials(),
+ self.os_env_vars)
+
+ def _get_credentials_missing_env(self, var):
+ dic = copy.deepcopy(self.os_environs)
+ dic.pop(var)
+ with mock.patch('functest.utils.openstack_utils.get_rc_env_vars',
+ return_value=self.env_cred_dict.keys()), \
+ mock.patch.dict('functest.utils.openstack_utils.os.environ',
+ dic,
+ clear=True):
+ self.assertRaises(openstack_utils.MissingEnvVar,
+ lambda: openstack_utils.get_credentials())
+
+ def test_get_credentials_missing_username(self):
+ self._get_credentials_missing_env('OS_USERNAME')
+
+ def test_get_credentials_missing_password(self):
+ self._get_credentials_missing_env('OS_PASSWORD')
+
+ def test_get_credentials_missing_auth_url(self):
+ self._get_credentials_missing_env('OS_AUTH_URL')
+
+ def test_get_credentials_missing_tenantname(self):
+ self._get_credentials_missing_env('OS_TENANT_NAME')
+
+ def test_get_credentials_missing_domainname(self):
+ self._get_credentials_missing_env('OS_USER_DOMAIN_NAME')
+
+ def test_get_credentials_missing_projectname(self):
+ self._get_credentials_missing_env('OS_PROJECT_NAME')
+
+ def test_get_credentials_missing_endpoint_type(self):
+ self._get_credentials_missing_env('OS_ENDPOINT_TYPE')
+
+ def test_source_credentials(self):
+ with mock.patch('functest.utils.openstack_utils.subprocess.Popen') \
+ as mock_subproc_popen, \
+ mock.patch('functest.utils.openstack_utils.os.environ'):
+ process_mock = mock.Mock()
+ attrs = {'communicate.return_value': ('OS_USER_NAME=test_name',
+ 'success')}
+ process_mock.configure_mock(**attrs)
+ mock_subproc_popen.return_value = process_mock
+
+ self.assertDictEqual(openstack_utils.source_credentials('rc_file'),
+ {'OS_USER_NAME': 'test_name'})
+
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value=None)
+ def test_get_keystone_client_version_missing_env(self, mock_os_getenv):
+ self.assertEqual(openstack_utils.get_keystone_client_version(),
+ openstack_utils.DEFAULT_API_VERSION)
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value='3')
+ def test_get_keystone_client_version_default(self, mock_os_getenv,
+ mock_logger_info):
+ self.assertEqual(openstack_utils.get_keystone_client_version(),
+ '3')
+ mock_logger_info.assert_called_once_with("OS_IDENTITY_API_VERSION is "
+ "set in env as '%s'", '3')
+
+ def test_get_keystone_client(self):
+ mock_keystone_obj = mock.Mock()
+ mock_session_obj = mock.Mock()
+ with mock.patch('functest.utils.openstack_utils'
+ '.get_keystone_client_version', return_value='3'), \
+ mock.patch('functest.utils.openstack_utils'
+ '.keystoneclient.Client',
+ return_value=mock_keystone_obj) \
+ as mock_key_client, \
+ mock.patch('functest.utils.openstack_utils.get_session',
+ return_value=mock_session_obj):
+ self.assertEqual(openstack_utils.get_keystone_client(),
+ mock_keystone_obj)
+ mock_key_client.assert_called_once_with('3',
+ session=mock_session_obj)
+
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value=None)
+ def test_get_nova_client_version_missing_env(self, mock_os_getenv):
+ self.assertEqual(openstack_utils.get_nova_client_version(),
+ openstack_utils.DEFAULT_API_VERSION)
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value='3')
+ def test_get_nova_client_version_default(self, mock_os_getenv,
+ mock_logger_info):
+ self.assertEqual(openstack_utils.get_nova_client_version(),
+ '3')
+ mock_logger_info.assert_called_once_with("OS_COMPUTE_API_VERSION is "
+ "set in env as '%s'", '3')
+
+ def test_get_nova_client(self):
+ mock_nova_obj = mock.Mock()
+ mock_session_obj = mock.Mock()
+ with mock.patch('functest.utils.openstack_utils'
+ '.get_nova_client_version', return_value='3'), \
+ mock.patch('functest.utils.openstack_utils'
+ '.novaclient.Client',
+ return_value=mock_nova_obj) \
+ as mock_nova_client, \
+ mock.patch('functest.utils.openstack_utils.get_session',
+ return_value=mock_session_obj):
+ self.assertEqual(openstack_utils.get_nova_client(),
+ mock_nova_obj)
+ mock_nova_client.assert_called_once_with('3',
+ session=mock_session_obj)
+
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value=None)
+ def test_get_cinder_client_version_missing_env(self, mock_os_getenv):
+ self.assertEqual(openstack_utils.get_cinder_client_version(),
+ openstack_utils.DEFAULT_API_VERSION)
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value='3')
+ def test_get_cinder_client_version_default(self, mock_os_getenv,
+ mock_logger_info):
+ self.assertEqual(openstack_utils.get_cinder_client_version(),
+ '3')
+ mock_logger_info.assert_called_once_with("OS_VOLUME_API_VERSION is "
+ "set in env as '%s'", '3')
+
+ def test_get_cinder_client(self):
+ mock_cinder_obj = mock.Mock()
+ mock_session_obj = mock.Mock()
+ with mock.patch('functest.utils.openstack_utils'
+ '.get_cinder_client_version', return_value='3'), \
+ mock.patch('functest.utils.openstack_utils'
+ '.cinderclient.Client',
+ return_value=mock_cinder_obj) \
+ as mock_cind_client, \
+ mock.patch('functest.utils.openstack_utils.get_session',
+ return_value=mock_session_obj):
+ self.assertEqual(openstack_utils.get_cinder_client(),
+ mock_cinder_obj)
+ mock_cind_client.assert_called_once_with('3',
+ session=mock_session_obj)
+
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value=None)
+ def test_get_neutron_client_version_missing_env(self, mock_os_getenv):
+ self.assertEqual(openstack_utils.get_neutron_client_version(),
+ openstack_utils.DEFAULT_API_VERSION)
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value='3')
+ def test_get_neutron_client_version_default(self, mock_os_getenv,
+ mock_logger_info):
+ self.assertEqual(openstack_utils.get_neutron_client_version(),
+ '3')
+ mock_logger_info.assert_called_once_with("OS_NETWORK_API_VERSION is "
+ "set in env as '%s'", '3')
+
+ def test_get_neutron_client(self):
+ mock_neutron_obj = mock.Mock()
+ mock_session_obj = mock.Mock()
+ with mock.patch('functest.utils.openstack_utils'
+ '.get_neutron_client_version', return_value='3'), \
+ mock.patch('functest.utils.openstack_utils'
+ '.neutronclient.Client',
+ return_value=mock_neutron_obj) \
+ as mock_neut_client, \
+ mock.patch('functest.utils.openstack_utils.get_session',
+ return_value=mock_session_obj):
+ self.assertEqual(openstack_utils.get_neutron_client(),
+ mock_neutron_obj)
+ mock_neut_client.assert_called_once_with('3',
+ session=mock_session_obj)
+
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value=None)
+ def test_get_glance_client_version_missing_env(self, mock_os_getenv):
+ self.assertEqual(openstack_utils.get_glance_client_version(),
+ openstack_utils.DEFAULT_API_VERSION)
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value='3')
+ def test_get_glance_client_version_default(self, mock_os_getenv,
+ mock_logger_info):
+ self.assertEqual(openstack_utils.get_glance_client_version(),
+ '3')
+ mock_logger_info.assert_called_once_with("OS_IMAGE_API_VERSION is "
+ "set in env as '%s'", '3')
+
+ def test_get_glance_client(self):
+ mock_glance_obj = mock.Mock()
+ mock_session_obj = mock.Mock()
+ with mock.patch('functest.utils.openstack_utils'
+ '.get_glance_client_version', return_value='3'), \
+ mock.patch('functest.utils.openstack_utils'
+ '.glanceclient.Client',
+ return_value=mock_glance_obj) \
+ as mock_glan_client, \
+ mock.patch('functest.utils.openstack_utils.get_session',
+ return_value=mock_session_obj):
+ self.assertEqual(openstack_utils.get_glance_client(),
+ mock_glance_obj)
+ mock_glan_client.assert_called_once_with('3',
+ session=mock_session_obj)
+
+ def test_get_instances_default(self):
+ self.assertEqual(openstack_utils.get_instances(self.nova_client),
+ [self.instance])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_instances_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_instances(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_instance_status_default(self):
+ self.assertEqual(openstack_utils.get_instance_status(self.nova_client,
+ self.instance),
+ 'ok')
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_instance_status_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_instance_status(Exception,
+ self.instance),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_instance_by_name_default(self):
+ self.assertEqual(openstack_utils.
+ get_instance_by_name(self.nova_client,
+ 'test_instance'),
+ self.instance)
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_instance_by_name_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_instance_by_name(Exception,
+ 'test_instance'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_flavor_id_default(self):
+ self.assertEqual(openstack_utils.
+ get_flavor_id(self.nova_client,
+ 'test_flavor'),
+ self.flavor.id)
+
+ def test_get_flavor_id_by_ram_range_default(self):
+ self.assertEqual(openstack_utils.
+ get_flavor_id_by_ram_range(self.nova_client,
+ 1, 3),
+ self.flavor.id)
+
+ def test_get_aggregates_default(self):
+ self.assertEqual(openstack_utils.
+ get_aggregates(self.nova_client),
+ [self.aggregate])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_aggregates_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_aggregates(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_aggregate_id_default(self):
+ with mock.patch('functest.utils.openstack_utils.get_aggregates',
+ return_value=[self.aggregate]):
+ self.assertEqual(openstack_utils.
+ get_aggregate_id(self.nova_client,
+ 'test_aggregate'),
+ 'aggregate_id')
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_aggregate_id_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_aggregate_id(Exception,
+ 'test_aggregate'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_availability_zone_names_default(self):
+ with mock.patch('functest.utils.openstack_utils'
+ '.get_availability_zones',
+ return_value=[self.availability_zone]):
+ self.assertEqual(openstack_utils.
+ get_availability_zone_names(self.nova_client),
+ ['test_azone'])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_availability_zone_names_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_availability_zone_names(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_availability_zones_default(self):
+ self.assertEqual(openstack_utils.
+ get_availability_zones(self.nova_client),
+ [self.availability_zone])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_availability_zones_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_availability_zones(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_floating_ips_default(self):
+ self.assertEqual(openstack_utils.
+ get_floating_ips(self.nova_client),
+ [self.floating_ip])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_floating_ips_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_floating_ips(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_hypervisors_default(self):
+ self.assertEqual(openstack_utils.
+ get_hypervisors(self.nova_client),
+ ['test_hostname'])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_hypervisors_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_hypervisors(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_create_aggregate_default(self):
+ self.assertTrue(openstack_utils.
+ create_aggregate(self.nova_client,
+ 'test_aggregate',
+ 'azone'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_aggregate_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ create_aggregate(Exception,
+ 'test_aggregate',
+ 'azone'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_add_host_to_aggregate_default(self):
+ with mock.patch('functest.utils.openstack_utils.get_aggregate_id'):
+ self.assertTrue(openstack_utils.
+ add_host_to_aggregate(self.nova_client,
+ 'test_aggregate',
+ 'test_hostname'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_add_host_to_aggregate_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ add_host_to_aggregate(Exception,
+ 'test_aggregate',
+ 'test_hostname'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_create_aggregate_with_host_default(self):
+ with mock.patch('functest.utils.openstack_utils.create_aggregate'), \
+ mock.patch('functest.utils.openstack_utils.'
+ 'add_host_to_aggregate'):
+ self.assertTrue(openstack_utils.
+ create_aggregate_with_host(self.nova_client,
+ 'test_aggregate',
+ 'test_azone',
+ 'test_hostname'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_aggregate_with_host_exception(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_utils.create_aggregate',
+ side_effect=Exception):
+ self.assertEqual(openstack_utils.
+ create_aggregate_with_host(Exception,
+ 'test_aggregate',
+ 'test_azone',
+ 'test_hostname'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_create_instance_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_nova_client',
+ return_value=self.nova_client):
+ self.assertEqual(openstack_utils.
+ create_instance('test_flavor',
+ 'image_id',
+ 'network_id'),
+ self.instance)
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_instance_exception(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_nova_client',
+ return_value=self.nova_client):
+ self.nova_client.flavors.find.side_effect = Exception
+ self.assertEqual(openstack_utils.
+ create_instance('test_flavor',
+ 'image_id',
+ 'network_id'),
+ None)
+ self.assertTrue(mock_logger_error)
+
+ def test_create_floating_ip_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_external_net_id',
+ return_value='external_net_id'):
+ exp_resp = {'fip_addr': 'test_ip', 'fip_id': 'fip_id'}
+ self.assertEqual(openstack_utils.
+ create_floating_ip(self.neutron_client),
+ exp_resp)
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_floating_ip_exception(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_external_net_id',
+ return_value='external_net_id'):
+ self.assertEqual(openstack_utils.
+ create_floating_ip(Exception),
+ None)
+ self.assertTrue(mock_logger_error)
+
+ def test_add_floating_ip_default(self):
+ with mock.patch('functest.utils.openstack_utils.get_aggregate_id'):
+ self.assertTrue(openstack_utils.
+ add_floating_ip(self.nova_client,
+ 'test_serverid',
+ 'test_floatingip_addr'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_add_floating_ip_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ add_floating_ip(Exception,
+ 'test_serverid',
+ 'test_floatingip_addr'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_instance_default(self):
+ self.assertTrue(openstack_utils.
+ delete_instance(self.nova_client,
+ 'instance_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_instance_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_instance(Exception,
+ 'instance_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_floating_ip_default(self):
+ self.assertTrue(openstack_utils.
+ delete_floating_ip(self.nova_client,
+ 'floating_ip_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_floating_ip_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_floating_ip(Exception,
+ 'floating_ip_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_remove_host_from_aggregate_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_aggregate_id'):
+ self.assertTrue(openstack_utils.
+ remove_host_from_aggregate(self.nova_client,
+ 'agg_name',
+ 'host_name'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_remove_host_from_aggregate_exception(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_aggregate_id', side_effect=Exception):
+ self.assertFalse(openstack_utils.
+ remove_host_from_aggregate(self.nova_client,
+ 'agg_name',
+ 'host_name'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_remove_hosts_from_aggregate_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_aggregate_id'), \
+ mock.patch('functest.utils.openstack_utils.'
+ 'remove_host_from_aggregate',
+ return_value=True) \
+ as mock_method:
+ openstack_utils.remove_hosts_from_aggregate(self.nova_client,
+ 'test_aggregate')
+ mock_method.assert_any_call(self.nova_client,
+ 'test_aggregate',
+ 'host_name')
+
+ def test_delete_aggregate_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'remove_hosts_from_aggregate'):
+ self.assertTrue(openstack_utils.
+ delete_aggregate(self.nova_client,
+ 'agg_name'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_aggregate_exception(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'remove_hosts_from_aggregate', side_effect=Exception):
+ self.assertFalse(openstack_utils.
+ delete_aggregate(self.nova_client,
+ 'agg_name'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_network_list_default(self):
+ self.assertEqual(openstack_utils.
+ get_network_list(self.neutron_client),
+ self.networks)
+
+ def test_get_network_list_missing_network(self):
+ self.assertEqual(openstack_utils.
+ get_network_list(self.empty_client),
+ None)
+
+ def test_get_router_list_default(self):
+ self.assertEqual(openstack_utils.
+ get_router_list(self.neutron_client),
+ [self.router])
+
+ def test_get_router_list_missing_router(self):
+ self.assertEqual(openstack_utils.
+ get_router_list(self.empty_client),
+ None)
+
+ def test_get_port_list_default(self):
+ self.assertEqual(openstack_utils.
+ get_port_list(self.neutron_client),
+ [self.port])
+
+ def test_get_port_list_missing_port(self):
+ self.assertEqual(openstack_utils.
+ get_port_list(self.empty_client),
+ None)
+
+ def test_get_network_id_default(self):
+ self.assertEqual(openstack_utils.
+ get_network_id(self.neutron_client,
+ 'test_network'),
+ 'network_id')
+
+ def test_get_subnet_id_default(self):
+ self.assertEqual(openstack_utils.
+ get_subnet_id(self.neutron_client,
+ 'test_subnet'),
+ 'subnet_id')
+
+ def test_get_router_id_default(self):
+ self.assertEqual(openstack_utils.
+ get_router_id(self.neutron_client,
+ 'test_router'),
+ 'router_id')
+
+ def test_get_private_net_default(self):
+ self.assertEqual(openstack_utils.
+ get_private_net(self.neutron_client),
+ self.networks[0])
+
+ def test_get_private_net_missing_net(self):
+ self.assertEqual(openstack_utils.
+ get_private_net(self.empty_client),
+ None)
+
+ def test_get_external_net_default(self):
+ self.assertEqual(openstack_utils.
+ get_external_net(self.neutron_client),
+ 'test_network1')
+
+ def test_get_external_net_missing_net(self):
+ self.assertEqual(openstack_utils.
+ get_external_net(self.empty_client),
+ None)
+
+ def test_get_external_net_id_default(self):
+ self.assertEqual(openstack_utils.
+ get_external_net_id(self.neutron_client),
+ 'network_id1')
+
+ def test_get_external_net_id_missing_net(self):
+ self.assertEqual(openstack_utils.
+ get_external_net_id(self.empty_client),
+ None)
+
+ def test_check_neutron_net_default(self):
+ self.assertTrue(openstack_utils.
+ check_neutron_net(self.neutron_client,
+ 'test_network'))
+
+ def test_check_neutron_net_missing_net(self):
+ self.assertFalse(openstack_utils.
+ check_neutron_net(self.empty_client,
+ 'test_network'))
+
+ def test_create_neutron_net_default(self):
+ self.assertEqual(openstack_utils.
+ create_neutron_net(self.neutron_client,
+ 'test_network'),
+ 'network_id')
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_neutron_net_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ create_neutron_net(Exception,
+ 'test_network'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_create_neutron_subnet_default(self):
+ self.assertEqual(openstack_utils.
+ create_neutron_subnet(self.neutron_client,
+ 'test_subnet',
+ 'test_cidr',
+ 'network_id'),
+ 'subnet_id')
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_neutron_subnet_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ create_neutron_subnet(Exception,
+ 'test_subnet',
+ 'test_cidr',
+ 'network_id'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_create_neutron_router_default(self):
+ self.assertEqual(openstack_utils.
+ create_neutron_router(self.neutron_client,
+ 'test_router'),
+ 'router_id')
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_neutron_router_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ create_neutron_router(Exception,
+ 'test_router'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_create_neutron_port_default(self):
+ self.assertEqual(openstack_utils.
+ create_neutron_port(self.neutron_client,
+ 'test_port',
+ 'network_id',
+ 'test_ip'),
+ 'port_id')
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_neutron_port_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ create_neutron_port(Exception,
+ 'test_port',
+ 'network_id',
+ 'test_ip'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_update_neutron_net_default(self):
+ self.assertTrue(openstack_utils.
+ update_neutron_net(self.neutron_client,
+ 'network_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_update_neutron_net_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ update_neutron_net(Exception,
+ 'network_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_update_neutron_port_default(self):
+ self.assertEqual(openstack_utils.
+ update_neutron_port(self.neutron_client,
+ 'port_id',
+ 'test_owner'),
+ 'port_id')
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_update_neutron_port_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ update_neutron_port(Exception,
+ 'port_id',
+ 'test_owner'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_add_interface_router_default(self):
+ self.assertTrue(openstack_utils.
+ add_interface_router(self.neutron_client,
+ 'router_id',
+ 'subnet_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_add_interface_router_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ add_interface_router(Exception,
+ 'router_id',
+ 'subnet_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_add_gateway_router_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_external_net_id',
+ return_value='network_id'):
+ self.assertTrue(openstack_utils.
+ add_gateway_router(self.neutron_client,
+ 'router_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_add_gateway_router_exception(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_external_net_id',
+ return_value='network_id'):
+ self.assertFalse(openstack_utils.
+ add_gateway_router(Exception,
+ 'router_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_neutron_net_default(self):
+ self.assertTrue(openstack_utils.
+ delete_neutron_net(self.neutron_client,
+ 'network_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_neutron_net_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_neutron_net(Exception,
+ 'network_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_neutron_subnet_default(self):
+ self.assertTrue(openstack_utils.
+ delete_neutron_subnet(self.neutron_client,
+ 'subnet_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_neutron_subnet_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_neutron_subnet(Exception,
+ 'subnet_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_neutron_router_default(self):
+ self.assertTrue(openstack_utils.
+ delete_neutron_router(self.neutron_client,
+ 'router_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_neutron_router_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_neutron_router(Exception,
+ 'router_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_neutron_port_default(self):
+ self.assertTrue(openstack_utils.
+ delete_neutron_port(self.neutron_client,
+ 'port_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_neutron_port_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_neutron_port(Exception,
+ 'port_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_remove_interface_router_default(self):
+ self.assertTrue(openstack_utils.
+ remove_interface_router(self.neutron_client,
+ 'router_id',
+ 'subnet_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_remove_interface_router_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ remove_interface_router(Exception,
+ 'router_id',
+ 'subnet_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_remove_gateway_router_default(self):
+ self.assertTrue(openstack_utils.
+ remove_gateway_router(self.neutron_client,
+ 'router_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_remove_gateway_router_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ remove_gateway_router(Exception,
+ 'router_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_create_bgpvpn(self):
+ self.assertEqual(openstack_utils.
+ create_bgpvpn(self.neutron_client),
+ self.mock_return)
+
+ def test_create_network_association(self):
+ self.assertEqual(openstack_utils.
+ create_network_association(self.neutron_client,
+ 'bgpvpn_id',
+ 'network_id'),
+ self.mock_return)
+
+ def test_create_router_association(self):
+ self.assertEqual(openstack_utils.
+ create_router_association(self.neutron_client,
+ 'bgpvpn_id',
+ 'router_id'),
+ self.mock_return)
+
+ def test_update_bgpvpn(self):
+ self.assertEqual(openstack_utils.
+ update_bgpvpn(self.neutron_client,
+ 'bgpvpn_id'),
+ self.mock_return)
+
+ def test_delete_bgpvpn(self):
+ self.assertEqual(openstack_utils.
+ delete_bgpvpn(self.neutron_client,
+ 'bgpvpn_id'),
+ self.mock_return)
+
+ def test_get_bgpvpn(self):
+ self.assertEqual(openstack_utils.
+ get_bgpvpn(self.neutron_client,
+ 'bgpvpn_id'),
+ self.mock_return)
+
+ def test_get_bgpvpn_routers(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_bgpvpn',
+ return_value={'bgpvpn':
+ {'routers': [self.router]}}):
+ self.assertEqual(openstack_utils.
+ get_bgpvpn_routers(self.neutron_client,
+ 'bgpvpn_id'),
+ [self.router])
+
+ def test_get_security_groups_default(self):
+ self.assertEqual(openstack_utils.
+ get_security_groups(self.neutron_client),
+ [self.sec_group])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_security_groups_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_security_groups(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_security_group_id_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_security_groups',
+ return_value=[self.sec_group]):
+ self.assertEqual(openstack_utils.
+ get_security_group_id(self.neutron_client,
+ 'test_sec_group'),
+ 'sec_group_id')
+
+ def test_create_security_group_default(self):
+ self.assertEqual(openstack_utils.
+ create_security_group(self.neutron_client,
+ 'test_sec_group',
+ 'sec_group_desc'),
+ self.sec_group)
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_security_group_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ create_security_group(Exception,
+ 'test_sec_group',
+ 'sec_group_desc'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_create_secgroup_rule_default(self):
+ self.assertTrue(openstack_utils.
+ create_secgroup_rule(self.neutron_client,
+ 'sg_id',
+ 'direction',
+ 'protocol',
+ 80,
+ 80))
+ self.assertTrue(openstack_utils.
+ create_secgroup_rule(self.neutron_client,
+ 'sg_id',
+ 'direction',
+ 'protocol'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_secgroup_rule_invalid_port_range(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ create_secgroup_rule(self.neutron_client,
+ 'sg_id',
+ 'direction',
+ 'protocol',
+ 80))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_secgroup_rule_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ create_secgroup_rule(Exception,
+ 'sg_id',
+ 'direction',
+ 'protocol'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ def test_create_security_group_full_default(self, mock_logger_info):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_security_group_id',
+ return_value='sg_id'):
+ self.assertEqual(openstack_utils.
+ create_security_group_full(self.neutron_client,
+ 'sg_name',
+ 'sg_desc'),
+ 'sg_id')
+ self.assertTrue(mock_logger_info)
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_security_group_full_sec_group_fail(self,
+ mock_logger_error,
+ mock_logger_info):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_security_group_id',
+ return_value=''), \
+ mock.patch('functest.utils.openstack_utils.'
+ 'create_security_group',
+ return_value=False):
+ self.assertEqual(openstack_utils.
+ create_security_group_full(self.neutron_client,
+ 'sg_name',
+ 'sg_desc'),
+ None)
+ self.assertTrue(mock_logger_error)
+ self.assertTrue(mock_logger_info)
+
+ @mock.patch('functest.utils.openstack_utils.logger.debug')
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_security_group_full_secgroup_rule_fail(self,
+ mock_logger_error,
+ mock_logger_info,
+ mock_logger_debug):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'get_security_group_id',
+ return_value=''), \
+ mock.patch('functest.utils.openstack_utils.'
+ 'create_security_group',
+ return_value={'id': 'sg_id',
+ 'name': 'sg_name'}), \
+ mock.patch('functest.utils.openstack_utils.'
+ 'create_secgroup_rule',
+ return_value=False):
+ self.assertEqual(openstack_utils.
+ create_security_group_full(self.neutron_client,
+ 'sg_name',
+ 'sg_desc'),
+ None)
+ self.assertTrue(mock_logger_error)
+ self.assertTrue(mock_logger_info)
+ self.assertTrue(mock_logger_debug)
+
+ def test_add_secgroup_to_instance_default(self):
+ self.assertTrue(openstack_utils.
+ add_secgroup_to_instance(self.nova_client,
+ 'instance_id',
+ 'sec_group_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_add_secgroup_to_instance_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ add_secgroup_to_instance(Exception,
+ 'instance_id',
+ 'sec_group_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_update_sg_quota_default(self):
+ self.assertTrue(openstack_utils.
+ update_sg_quota(self.neutron_client,
+ 'tenant_id',
+ 'sg_quota',
+ 'sg_rule_quota'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_update_sg_quota_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ update_sg_quota(Exception,
+ 'tenant_id',
+ 'sg_quota',
+ 'sg_rule_quota'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_security_group_default(self):
+ self.assertTrue(openstack_utils.
+ delete_security_group(self.neutron_client,
+ 'sec_group_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_security_group_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_security_group(Exception,
+ 'sec_group_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_images_default(self):
+ self.assertEqual(openstack_utils.
+ get_images(self.nova_client),
+ [self.image])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_images_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_images(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_image_id_default(self):
+ self.assertEqual(openstack_utils.
+ get_image_id(self.glance_client,
+ 'test_image'),
+ 'image_id')
+
+ # create_glance_image, get_or_create_image
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_glance_image_file_present(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'os.path.isfile',
+ return_value=False):
+ self.assertEqual(openstack_utils.
+ create_glance_image(self.glance_client,
+ 'test_image',
+ 'file_path'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ def test_create_glance_image_already_exist(self, mock_logger_info):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'os.path.isfile',
+ return_value=True), \
+ mock.patch('functest.utils.openstack_utils.get_image_id',
+ return_value='image_id'):
+ self.assertEqual(openstack_utils.
+ create_glance_image(self.glance_client,
+ 'test_image',
+ 'file_path'),
+ 'image_id')
+ self.assertTrue(mock_logger_info.called)
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ def test_create_glance_image_default(self, mock_logger_info):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'os.path.isfile',
+ return_value=True), \
+ mock.patch('functest.utils.openstack_utils.get_image_id',
+ return_value=''), \
+ mock.patch('__builtin__.open',
+ mock.mock_open(read_data='1')) as m:
+ self.assertEqual(openstack_utils.
+ create_glance_image(self.glance_client,
+ 'test_image',
+ 'file_path'),
+ 'image_id')
+ m.assert_called_once_with('file_path')
+ self.assertTrue(mock_logger_info.called)
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_glance_image_exception(self, mock_logger_error):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'os.path.isfile',
+ return_value=True), \
+ mock.patch('functest.utils.openstack_utils.get_image_id',
+ side_effect=Exception):
+ self.assertEqual(openstack_utils.
+ create_glance_image(self.glance_client,
+ 'test_image',
+ 'file_path'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_glance_image_default(self):
+ self.assertTrue(openstack_utils.
+ delete_glance_image(self.nova_client,
+ 'image_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_glance_image_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_glance_image(Exception,
+ 'image_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_volumes_default(self):
+ self.assertEqual(openstack_utils.
+ get_volumes(self.cinder_client),
+ [self.volume])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_volumes_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_volumes(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_list_volume_types_default_private(self):
+ self.assertEqual(openstack_utils.
+ list_volume_types(self.cinder_client,
+ public=False,
+ private=True),
+ [self.volume_types[1]])
+
+ def test_list_volume_types_default_public(self):
+ self.assertEqual(openstack_utils.
+ list_volume_types(self.cinder_client,
+ public=True,
+ private=False),
+ [self.volume_types[0]])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_list_volume_types_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ list_volume_types(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_create_volume_type_default(self):
+ self.assertEqual(openstack_utils.
+ create_volume_type(self.cinder_client,
+ 'test_volume_type'),
+ self.volume_types[0])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_volume_type_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ create_volume_type(Exception,
+ 'test_volume_type'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_update_cinder_quota_default(self):
+ self.assertTrue(openstack_utils.
+ update_cinder_quota(self.cinder_client,
+ 'tenant_id',
+ 'vols_quota',
+ 'snap_quota',
+ 'giga_quota'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_update_cinder_quota_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ update_cinder_quota(Exception,
+ 'tenant_id',
+ 'vols_quota',
+ 'snap_quota',
+ 'giga_quota'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_volume_default(self):
+ self.assertTrue(openstack_utils.
+ delete_volume(self.cinder_client,
+ 'volume_id',
+ forced=False))
+
+ self.assertTrue(openstack_utils.
+ delete_volume(self.cinder_client,
+ 'volume_id',
+ forced=True))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_volume_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_volume(Exception,
+ 'volume_id',
+ forced=True))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_volume_type_default(self):
+ self.assertTrue(openstack_utils.
+ delete_volume_type(self.cinder_client,
+ self.volume_types[0]))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_volume_type_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_volume_type(Exception,
+ self.volume_types[0]))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_tenants_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=True):
+ self.assertEqual(openstack_utils.
+ get_tenants(self.keystone_client),
+ [self.tenant])
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=False):
+ self.assertEqual(openstack_utils.
+ get_tenants(self.keystone_client),
+ [self.tenant])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_tenants_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_tenants(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_users_default(self):
+ self.assertEqual(openstack_utils.
+ get_users(self.keystone_client),
+ [self.user])
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_users_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_users(Exception),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_get_tenant_id_default(self):
+ self.assertEqual(openstack_utils.
+ get_tenant_id(self.keystone_client,
+ 'test_tenant'),
+ 'tenant_id')
+
+ def test_get_user_id_default(self):
+ self.assertEqual(openstack_utils.
+ get_user_id(self.keystone_client,
+ 'test_user'),
+ 'user_id')
+
+ def test_get_role_id_default(self):
+ self.assertEqual(openstack_utils.
+ get_role_id(self.keystone_client,
+ 'test_role'),
+ 'role_id')
+
+ def test_create_tenant_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=True):
+ self.assertEqual(openstack_utils.
+ create_tenant(self.keystone_client,
+ 'test_tenant',
+ 'tenant_desc'),
+ 'tenant_id')
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=False):
+ self.assertEqual(openstack_utils.
+ create_tenant(self.keystone_client,
+ 'test_tenant',
+ 'tenant_desc'),
+ 'tenant_id')
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_tenant_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ create_tenant(Exception,
+ 'test_tenant',
+ 'tenant_desc'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_create_user_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=True):
+ self.assertEqual(openstack_utils.
+ create_user(self.keystone_client,
+ 'test_user',
+ 'password',
+ 'email',
+ 'tenant_id'),
+ 'user_id')
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=False):
+ self.assertEqual(openstack_utils.
+ create_user(self.keystone_client,
+ 'test_user',
+ 'password',
+ 'email',
+ 'tenant_id'),
+ 'user_id')
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_create_user_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ create_user(Exception,
+ 'test_user',
+ 'password',
+ 'email',
+ 'tenant_id'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
+ def test_add_role_user_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=True):
+ self.assertTrue(openstack_utils.
+ add_role_user(self.keystone_client,
+ 'user_id',
+ 'role_id',
+ 'tenant_id'))
+
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=False):
+ self.assertTrue(openstack_utils.
+ add_role_user(self.keystone_client,
+ 'user_id',
+ 'role_id',
+ 'tenant_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_add_role_user_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ add_role_user(Exception,
+ 'user_id',
+ 'role_id',
+ 'tenant_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_tenant_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=True):
+ self.assertTrue(openstack_utils.
+ delete_tenant(self.keystone_client,
+ 'tenant_id'))
+
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=False):
+ self.assertTrue(openstack_utils.
+ delete_tenant(self.keystone_client,
+ 'tenant_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_tenant_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_tenant(Exception,
+ 'tenant_id'))
+ self.assertTrue(mock_logger_error.called)
+
+ def test_delete_user_default(self):
+ self.assertTrue(openstack_utils.
+ delete_user(self.keystone_client,
+ 'user_id'))
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_delete_user_exception(self, mock_logger_error):
+ self.assertFalse(openstack_utils.
+ delete_user(Exception,
+ 'user_id'))
+ self.assertTrue(mock_logger_error.called)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/utils/test_utils.py b/functest/tests/unit/utils/test_utils.py
deleted file mode 100644
index 8b6c5e1b9..000000000
--- a/functest/tests/unit/utils/test_utils.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 Orange 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
-
-import logging
-import mock
-import unittest
-import urllib2
-
-from functest.utils import functest_utils
-
-
-class FunctestUtilsTesting(unittest.TestCase):
-
- logging.disable(logging.CRITICAL)
-
- def setUp(self):
- self.url = 'http://www.opnfv.org/'
- self.timeout = 5
-
- @mock.patch('urllib2.urlopen',
- side_effect=urllib2.URLError('no host given'))
- def test_check_internet_connectivity_failed(self, mock_method):
- self.assertFalse(functest_utils.check_internet_connectivity())
- mock_method.assert_called_once_with(self.url, timeout=self.timeout)
-
- @mock.patch('urllib2.urlopen')
- def test_check_internet_connectivity_default(self, mock_method):
- self.assertTrue(functest_utils.check_internet_connectivity())
- mock_method.assert_called_once_with(self.url, timeout=self.timeout)
-
- @mock.patch('urllib2.urlopen')
- def test_check_internet_connectivity_debian(self, mock_method):
- self.url = "https://www.debian.org/"
- self.assertTrue(functest_utils.check_internet_connectivity(self.url))
- mock_method.assert_called_once_with(self.url, timeout=self.timeout)
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/functest/utils/config.py b/functest/utils/config.py
index 4cee63494..84166c1d3 100644
--- a/functest/utils/config.py
+++ b/functest/utils/config.py
@@ -11,20 +11,25 @@ class Config(object):
try:
with open(self.config_functest) as f:
self.functest_yaml = yaml.safe_load(f)
- self.parse(None, self.functest_yaml)
+ self._parse(None, self.functest_yaml)
except:
raise Exception('Parse {} failed'.format(self.config_functest))
+ self._set_others()
- def parse(self, attr_now, left_parametes):
+ def _parse(self, attr_now, left_parametes):
for param_n, param_v in left_parametes.iteritems():
- attr_further = self.get_attr_further(attr_now, param_n)
+ attr_further = self._get_attr_further(attr_now, param_n)
if not isinstance(param_v, dict):
self.__setattr__(attr_further, param_v)
else:
- self.parse(attr_further, param_v)
+ self._parse(attr_further, param_v)
- def get_attr_further(self, attr_now, next):
+ def _get_attr_further(self, attr_now, next):
return attr_now if next == 'general' else (
'{}_{}'.format(attr_now, next) if attr_now else next)
+ def _set_others(self):
+ self.env_active = os.path.join(self.dir_functest_conf, "env_active")
+
+
CONF = Config()
diff --git a/functest/utils/env.py b/functest/utils/env.py
index b6af767da..fa5245fb6 100644
--- a/functest/utils/env.py
+++ b/functest/utils/env.py
@@ -1,18 +1,41 @@
import os
+import re
default_envs = {
'NODE_NAME': 'unknown_pod',
- 'CI_DEBUG': 'true'
+ 'CI_DEBUG': 'true',
+ 'DEPLOY_SCENARIO': 'os-nosdn-nofeature-noha',
+ 'DEPLOY_TYPE': 'virt',
+ 'INSTALLER_TYPE': None,
+ 'INSTALLER_IP': None,
+ 'BUILD_TAG': None,
+ 'OS_ENDPOINT_TYPE': None,
+ 'OS_AUTH_URL': None
}
class Environment(object):
+
def __init__(self):
for k, v in os.environ.iteritems():
self.__setattr__(k, v)
for k, v in default_envs.iteritems():
if k not in os.environ:
self.__setattr__(k, v)
+ self._set_ci_run()
+ self._set_ci_loop()
+
+ def _set_ci_run(self):
+ if self.BUILD_TAG:
+ self.IS_CI_RUN = True
+ else:
+ self.IS_CI_RUN = False
+
+ def _set_ci_loop(self):
+ if self.BUILD_TAG and re.search("daily", self.BUILD_TAG):
+ self.CI_LOOP = "daily"
+ else:
+ self.CI_LOOP = "weekly"
ENV = Environment()
diff --git a/functest/utils/functest_constants.py b/functest/utils/functest_constants.py
index 2664ace1f..7fb03e8a2 100644
--- a/functest/utils/functest_constants.py
+++ b/functest/utils/functest_constants.py
@@ -7,8 +7,9 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
import os
-import functest.utils.functest_utils as ft_utils
+
import functest.utils.functest_logger as ft_logger
+import functest.utils.functest_utils as ft_utils
logger = ft_logger.Logger("functest_constants").getLogger()
@@ -60,25 +61,25 @@ def get_value(functest_config_key, env_variable):
return constant
-HOME = get_value('general.directories.dir_home', 'HOME')
-REPOS_DIR = get_value('general.directories.dir_repos', 'REPOS_DIR')
-FUNCTEST_BASE_DIR = get_value('general.directories.dir_functest',
+HOME = get_value('general.dir.home', 'HOME')
+REPOS_DIR = get_value('general.dir.repos', 'REPOS_DIR')
+FUNCTEST_BASE_DIR = get_value('general.dir.functest',
'FUNCTEST_BASE_DIR')
-FUNCTEST_REPO_DIR = get_value('general.directories.dir_repo_functest',
+FUNCTEST_REPO_DIR = get_value('general.dir.repo_functest',
'FUNCTEST_REPO_DIR')
-FUNCTEST_TEST_DIR = get_value('general.directories.dir_functest_test',
+FUNCTEST_TEST_DIR = get_value('general.dir.functest_test',
'FUNCTEST_TEST_DIR')
-FUNCTEST_CONF_DIR = get_value('general.directories.dir_functest_conf',
+FUNCTEST_CONF_DIR = get_value('general.dir.functest_conf',
'FUNCTEST_CONF_DIR')
-FUNCTEST_DATA_DIR = get_value('general.directories.dir_functest_data',
+FUNCTEST_DATA_DIR = get_value('general.dir.functest_data',
'FUNCTEST_DATA_DIR')
-FUNCTEST_RESULTS_DIR = get_value('general.directories.dir_results',
+FUNCTEST_RESULTS_DIR = get_value('general.dir.results',
'FUNCTEST_RESULTS_DIR')
FUNCTEST_TESTCASES_YAML = get_value('general.functest.testcases_yaml',
'FUNCTEST_TESTCASES_YAML')
RALLY_DEPLOYMENT_NAME = get_value('rally.deployment_name',
'RALLY_DEPLOYMENT_NAME')
-TEMPEST_REPO_DIR = get_value('general.directories.dir_repo_tempest',
+TEMPEST_REPO_DIR = get_value('general.dir.repo_tempest',
'TEMPEST_REPO_DIR')
ENV_FILE = os.path.join(FUNCTEST_CONF_DIR, "env_active")
@@ -87,22 +88,22 @@ OPENSTACK_CREDS = get_value('general.openstack.creds', 'creds')
OPENSTACK_SNAPSHOT_FILE = get_value('general.openstack.snapshot_file',
'OPENSTACK_SNAPSHOT_FILE')
-DOMINO_REPO_DIR = get_value('general.directories.dir_repo_domino',
+DOMINO_REPO_DIR = get_value('general.dir.repo_domino',
'DOMINO_REPO_DIR')
-SDNVPN_REPO_DIR = get_value('general.directories.dir_repo_sdnvpn',
+SDNVPN_REPO_DIR = get_value('general.dir.repo_sdnvpn',
'SDNVPN_REPO_DIR')
-SFC_REPO_DIR = get_value('general.directories.dir_repo_sfc',
+SFC_REPO_DIR = get_value('general.dir.repo_sfc',
'SFC_REPO_DIR')
ONOS_SFC_IMAGE_NAME = get_value('onos_sfc.image_name',
'ONOS_SFC_IMAGE_NAME')
ONOS_SFC_IMAGE_FILENAME = get_value('onos_sfc.image_file_name',
'ONOS_SFC_IMAGE_FILENAME')
-ONOS_SFC_RELATIVE_PATH = get_value('general.directories.dir_onos_sfc',
+ONOS_SFC_RELATIVE_PATH = get_value('general.dir.dir_onos_sfc',
'ONOS_SFC_RELATIVE_PATH')
ONOS_SFC_IMAGE_BASE_URL = get_value('onos_sfc.image_base_url',
'ONOS_SFC_IMAGE_BASE_URL')
-RALLY_RELATIVE_PATH = get_value('general.directories.dir_rally',
+RALLY_RELATIVE_PATH = get_value('general.dir.rally',
'RALLY_RELATIVE_PATH')
RALLY_PRIVATE_NET_NAME = get_value('rally.network_name',
'RALLY_PRIVATE_NET_NAME')
@@ -111,7 +112,7 @@ RALLY_PRIVATE_SUBNET_NAME = get_value('rally.subnet_name',
RALLY_PRIVATE_SUBNET_CIDR = get_value('rally.subnet_cidr',
'RALLY_PRIVATE_SUBNET_CIDR')
RALLY_ROUTER_NAME = get_value('rally.router_name', 'RALLY_ROUTER_NAME')
-RALLY_INSTALLATION_DIR = get_value('general.directories.dir_rally_inst',
+RALLY_INSTALLATION_DIR = get_value('general.dir.rally_inst',
'RALLY_INSTALLATION_DIR')
GLANCE_IMAGE_NAME = get_value('general.openstack.image_name',
'GLANCE_IMAGE_NAME')
@@ -149,24 +150,24 @@ TEMPEST_USE_CUSTOM_IMAGES = get_value('tempest.use_custom_images',
'TEMPEST_USE_CUSTOM_IMAGES')
TEMPEST_USE_CUSTOM_FLAVORS = get_value('tempest.use_custom_flavors',
'TEMPEST_USE_CUSTOM_FLAVORS')
-TEMPEST_TEST_LIST_DIR = get_value('general.directories.dir_tempest_cases',
+TEMPEST_TEST_LIST_DIR = get_value('general.dir.tempest_cases',
'TEMPEST_TEST_LIST_DIR')
NAME_VM_1 = get_value('vping.vm_name_1', 'NAME_VM_1')
NAME_VM_2 = get_value('vping.vm_name_2', 'NAME_VM_2')
PING_TIMEOUT = get_value('vping.ping_timeout', 'PING_TIMEOUT')
VPING__IMAGE_NAME = get_value('vping.image_name', 'VPING__IMAGE_NAME')
VPING_VM_FLAVOR = get_value('vping.vm_flavor', 'VPING_VM_FLAVOR')
-VPING_PRIVATE_NET_NAME = get_value('vping.vping_private_net_name',
+VPING_PRIVATE_NET_NAME = get_value('vping.private_net_name',
'VPING_PRIVATE_NET_NAME')
-VPING_PRIVATE_SUBNET_NAME = get_value('vping.vping_private_subnet_name',
+VPING_PRIVATE_SUBNET_NAME = get_value('vping.private_subnet_name',
'VPING_PRIVATE_SUBNET_NAME')
-VPING_PRIVATE_SUBNET_CIDR = get_value('vping.vping_private_subnet_cidr',
+VPING_PRIVATE_SUBNET_CIDR = get_value('vping.private_subnet_cidr',
'VPING_PRIVATE_SUBNET_CIDR')
-VPING_ROUTER_NAME = get_value('vping.vping_router_name',
+VPING_ROUTER_NAME = get_value('vping.router_name',
'VPING_ROUTER_NAME')
-VPING_SECGROUP_NAME = get_value('vping.vping_sg_name',
+VPING_SECGROUP_NAME = get_value('vping.sg_name',
'VPING_SECGROUP_NAME')
-VPING_SECGROUP_DESCR = get_value('vping.vping_sg_descr',
+VPING_SECGROUP_DESCR = get_value('vping.sg_desc',
'VPING_SECGROUP_DESCR')
ONOSBENCH_USERNAME = get_value('ONOS.general.onosbench_username',
'ONOSBENCH_USERNAME')
@@ -192,7 +193,7 @@ ONOS_INSTALLER_MASTER_USERNAME = get_value(
ONOS_INSTALLER_MASTER_PASSWORD = get_value(
'ONOS.environment.installer_master_password',
'ONOS_INSTALLER_MASTER_PASSWORD')
-PROMISE_REPO_DIR = get_value('general.directories.dir_repo_promise',
+PROMISE_REPO_DIR = get_value('general.dir.dir_repo_promise',
'PROMISE_REPO_DIR')
PROMISE_TENANT_NAME = get_value('promise.tenant_name',
'PROMISE_TENANT_NAME')
@@ -217,48 +218,28 @@ PROMISE_SUBNET_CIDR = get_value('promise.subnet_cidr',
'PROMISE_SUBNET_CIDR')
PROMISE_ROUTER_NAME = get_value('promise.router_name',
'PROMISE_ROUTER_NAME')
-DOCTOR_REPO_DIR = get_value('general.directories.dir_repo_doctor',
+DOCTOR_REPO_DIR = get_value('general.dir.dir_repo_doctor',
'DOCTOR_REPO_DIR')
-COPPER_REPO_DIR = get_value('general.directories.dir_repo_copper',
+COPPER_REPO_DIR = get_value('general.dir.repo_copper',
'COPPER_REPO_DIR')
-EXAMPLE_INSTANCE_NAME = get_value('example.example_vm_name',
+EXAMPLE_INSTANCE_NAME = get_value('example.vm_name',
'EXAMPLE_INSTANCE_NAME')
-EXAMPLE_FLAVOR = get_value('example.example_flavor', 'EXAMPLE_FLAVOR')
-EXAMPLE_IMAGE_NAME = get_value('example.example_image_name',
+EXAMPLE_FLAVOR = get_value('example.flavor', 'EXAMPLE_FLAVOR')
+EXAMPLE_IMAGE_NAME = get_value('example.image_name',
'EXAMPLE_IMAGE_NAME')
-EXAMPLE_PRIVATE_NET_NAME = get_value('example.example_private_net_name',
+EXAMPLE_PRIVATE_NET_NAME = get_value('example.private_net_name',
'EXAMPLE_PRIVATE_NET_NAME')
EXAMPLE_PRIVATE_SUBNET_NAME = get_value(
- 'example.example_private_subnet_name',
+ 'example.private_subnet_name',
'EXAMPLE_PRIVATE_SUBNET_NAME')
EXAMPLE_PRIVATE_SUBNET_CIDR = get_value(
- 'example.example_private_subnet_cidr',
+ 'example.private_subnet_cidr',
'EXAMPLE_PRIVATE_SUBNET_CIDR')
-EXAMPLE_ROUTER_NAME = get_value('example.example_router_name',
+EXAMPLE_ROUTER_NAME = get_value('example.router_name',
'EXAMPLE_ROUTER_NAME')
-EXAMPLE_SECGROUP_NAME = get_value('example.example_sg_name',
+EXAMPLE_SECGROUP_NAME = get_value('example.sg_name',
'EXAMPLE_SECGROUP_NAME')
-EXAMPLE_SECGROUP_DESCR = get_value('example.example_sg_descr',
+EXAMPLE_SECGROUP_DESCR = get_value('example.sg_desc',
'EXAMPLE_SECGROUP_DESCR')
-VIMS_DATA_DIR = get_value('general.directories.dir_vIMS_data',
- 'VIMS_DATA_DIR')
-VIMS_TEST_DIR = get_value('general.directories.dir_repo_vims_test',
- 'VIMS_TEST_DIR')
-VIMS_TENANT_NAME = get_value('vIMS.general.tenant_name',
- 'VIMS_TENANT_NAME')
-VIMS_TENANT_DESCRIPTION = get_value('vIMS.general.tenant_description',
- 'VIMS_TENANT_DESCRIPTION')
-VIMS_IMAGES = get_value('vIMS.general.images', 'VIMS_IMAGES')
-CFY_MANAGER_BLUEPRINT = get_value('vIMS.cloudify.blueprint',
- 'CFY_MANAGER_BLUEPRINT')
-CFY_MANAGER_REQUIERMENTS = get_value('vIMS.cloudify.requierments',
- 'CFY_MANAGER_REQUIERMENTS')
-CFY_INPUTS = get_value('vIMS.cloudify.inputs', 'CFY_INPUTS')
-CW_BLUEPRINT = get_value('vIMS.clearwater.blueprint', 'CW_BLUEPRINT')
-CW_DEPLOYMENT_NAME = get_value('vIMS.clearwater.deployment-name',
- 'CW_DEPLOYMENT_NAME')
-CW_INPUTS = get_value('vIMS.clearwater.inputs', 'CW_INPUTS')
-CW_REQUIERMENTS = get_value('vIMS.clearwater.requierments',
- 'CW_REQUIERMENTS')
-PARSER_REPO_DIR = get_value('general.directories.dir_repo_parser',
+PARSER_REPO_DIR = get_value('general.dir.repo_parser',
'PARSER_REPO_DIR')
diff --git a/functest/utils/functest_logger.py b/functest/utils/functest_logger.py
index b154f563d..c0fba082a 100644
--- a/functest/utils/functest_logger.py
+++ b/functest/utils/functest_logger.py
@@ -40,8 +40,10 @@ class Logger:
ch.setFormatter(formatter)
if CI_DEBUG is not None and CI_DEBUG.lower() == "true":
ch.setLevel(logging.DEBUG)
+ self.logger.parent.level = logging.DEBUG
else:
ch.setLevel(logging.INFO)
+ self.logger.parent.level = logging.INFO
self.logger.addHandler(ch)
hdlr = logging.FileHandler('/home/opnfv/functest/results/functest.log')
diff --git a/functest/utils/functest_utils.py b/functest/utils/functest_utils.py
index b1e4d3cdb..2bf87a05c 100644
--- a/functest/utils/functest_utils.py
+++ b/functest/utils/functest_utils.py
@@ -7,12 +7,14 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
#
+import functools
import json
import os
import re
import shutil
import subprocess
import sys
+import time
import urllib2
from datetime import datetime as dt
@@ -21,11 +23,10 @@ import requests
import yaml
from git import Repo
-import time
-import functools
-
+from functest.utils.constants import CONST
import functest.utils.functest_logger as ft_logger
+
logger = ft_logger.Logger("functest_utils").getLogger()
@@ -182,13 +183,43 @@ def logger_test_results(project, case_name, status, details):
'd': details})
+def write_results_to_file(project, case_name, start_date,
+ stop_date, criteria, details):
+ file_path = re.split(r'://', CONST.results_test_db_url)[1]
+
+ try:
+ installer = os.environ['INSTALLER_TYPE']
+ scenario = os.environ['DEPLOY_SCENARIO']
+ pod_name = os.environ['NODE_NAME']
+ except KeyError as e:
+ logger.error("Please set env var: " + str(e))
+ return False
+
+ test_start = dt.fromtimestamp(start_date).strftime('%Y-%m-%d %H:%M:%S')
+ test_stop = dt.fromtimestamp(stop_date).strftime('%Y-%m-%d %H:%M:%S')
+
+ params = {"project_name": project, "case_name": case_name,
+ "pod_name": pod_name, "installer": installer,
+ "scenario": scenario, "criteria": criteria,
+ "start_date": test_start, "stop_date": test_stop,
+ "details": details}
+ try:
+ with open(file_path, "a+w") as outfile:
+ json.dump(params, outfile)
+ outfile.write("\n")
+ return True
+ except Exception as e:
+ logger.error("write result data into a file failed: %s" % e)
+ return False
+
+
def push_results_to_db(project, case_name,
start_date, stop_date, criteria, details):
"""
POST results to the Result target DB
"""
# Retrieve params from CI and conf
- url = get_db_url() + "/results"
+ url = CONST.results_test_db_url + "/results"
try:
installer = os.environ['INSTALLER_TYPE']
@@ -321,26 +352,6 @@ def execute_command(cmd, info=False, error_msg="",
return returncode
-def get_deployment_dir():
- """
- Returns current Rally deployment directory
- """
- deployment_name = get_functest_config('rally.deployment_name')
- rally_dir = get_functest_config('general.directories.dir_rally_inst')
- cmd = ("rally deployment list | awk '/" + deployment_name +
- "/ {print $2}'")
- p = subprocess.Popen(cmd, shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- deployment_uuid = p.stdout.readline().rstrip()
- if deployment_uuid == "":
- logger.error("Rally deployment not found.")
- exit(-1)
- deployment_dir = (rally_dir + "/tempest/for-deployment-" +
- deployment_uuid)
- return deployment_dir
-
-
def get_dict_by_test(testname):
with open(get_testcases_file_dir()) as f:
testcases_yaml = yaml.safe_load(f)
diff --git a/functest/utils/openstack_clean.py b/functest/utils/openstack_clean.py
index c08568bde..15a8f33d5 100755
--- a/functest/utils/openstack_clean.py
+++ b/functest/utils/openstack_clean.py
@@ -23,14 +23,16 @@
#
import time
+
+import yaml
+
import functest.utils.functest_logger as ft_logger
import functest.utils.openstack_utils as os_utils
-import yaml
-import functest.utils.functest_constants as ft_constants
+from functest.utils.constants import CONST
logger = ft_logger.Logger("openstack_clean").getLogger()
-OS_SNAPSHOT_FILE = ft_constants.OPENSTACK_SNAPSHOT_FILE
+OS_SNAPSHOT_FILE = CONST.openstack_snapshot_file
def separator():
@@ -395,7 +397,7 @@ def main():
default_security_groups = snapshot_yaml.get('secgroups')
default_floatingips = snapshot_yaml.get('floatingips')
default_users = snapshot_yaml.get('users')
- # default_tenants = snapshot_yaml.get('tenants')
+ default_tenants = snapshot_yaml.get('tenants')
if not os_utils.check_credentials():
logger.error("Please source the openrc credentials and run "
@@ -416,10 +418,8 @@ def main():
separator()
remove_users(keystone_client, default_users)
separator()
- # TODO (Helen) tenant does not exist in V3
- # need to figure our anohter general verification point
- # remove_tenants(keystone_client, default_tenants)
- # separator()
+ remove_tenants(keystone_client, default_tenants)
+ separator()
if __name__ == '__main__':
diff --git a/functest/utils/openstack_snapshot.py b/functest/utils/openstack_snapshot.py
index 5b50ffa50..e64030f75 100755
--- a/functest/utils/openstack_snapshot.py
+++ b/functest/utils/openstack_snapshot.py
@@ -20,15 +20,16 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
+import yaml
+
import functest.utils.functest_logger as ft_logger
import functest.utils.openstack_utils as os_utils
-import yaml
-import functest.utils.functest_constants as ft_constants
+from functest.utils.constants import CONST
logger = ft_logger.Logger("openstack_snapshot").getLogger()
-OS_SNAPSHOT_FILE = ft_constants.OPENSTACK_SNAPSHOT_FILE
+OS_SNAPSHOT_FILE = CONST.openstack_snapshot_file
def separator():
@@ -149,7 +150,7 @@ def main():
snapshot.update(get_security_groups(neutron_client))
snapshot.update(get_floatinips(nova_client))
snapshot.update(get_users(keystone_client))
- # snapshot.update(get_tenants(keystone_client))
+ snapshot.update(get_tenants(keystone_client))
with open(OS_SNAPSHOT_FILE, 'w+') as yaml_file:
yaml_file.write(yaml.safe_dump(snapshot, default_flow_style=False))
diff --git a/functest/utils/openstack_utils.py b/functest/utils/openstack_utils.py
index ec784121b..64f18504d 100755
--- a/functest/utils/openstack_utils.py
+++ b/functest/utils/openstack_utils.py
@@ -52,14 +52,13 @@ def is_keystone_v3():
def get_rc_env_vars():
- keystone_v3 = is_keystone_v3()
env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD']
- if keystone_v3 is False:
- env_vars.extend(['OS_TENANT_NAME'])
- else:
+ if is_keystone_v3():
env_vars.extend(['OS_PROJECT_NAME',
'OS_USER_DOMAIN_NAME',
'OS_PROJECT_DOMAIN_NAME'])
+ else:
+ env_vars.extend(['OS_TENANT_NAME'])
return env_vars
@@ -86,7 +85,7 @@ def get_env_cred_dict():
return env_cred_dict
-def get_credentials():
+def get_credentials(other_creds={}):
"""Returns a creds dictionary filled with parsed from env
"""
creds = {}
@@ -99,6 +98,16 @@ def get_credentials():
else:
creds_key = env_cred_dict.get(envvar)
creds.update({creds_key: os.getenv(envvar)})
+
+ if 'tenant' in other_creds.keys():
+ if is_keystone_v3():
+ tenant = 'project_name'
+ else:
+ tenant = 'tenant_name'
+ other_creds[tenant] = other_creds.pop('tenant')
+
+ creds.update(other_creds)
+
return creds
@@ -138,9 +147,9 @@ def get_credentials_for_rally():
return rally_conf
-def get_session_auth():
+def get_session_auth(other_creds={}):
loader = loading.get_plugin_loader('password')
- creds = get_credentials()
+ creds = get_credentials(other_creds)
auth = loader.load_from_options(**creds)
return auth
@@ -152,8 +161,8 @@ def get_endpoint(service_type, endpoint_type='publicURL'):
endpoint_type=endpoint_type)
-def get_session():
- auth = get_session_auth()
+def get_session(other_creds={}):
+ auth = get_session_auth(other_creds)
return session.Session(auth=auth)
@@ -169,8 +178,8 @@ def get_keystone_client_version():
return DEFAULT_API_VERSION
-def get_keystone_client():
- sess = get_session()
+def get_keystone_client(other_creds={}):
+ sess = get_session(other_creds)
return keystoneclient.Client(get_keystone_client_version(), session=sess)
@@ -183,8 +192,8 @@ def get_nova_client_version():
return DEFAULT_API_VERSION
-def get_nova_client():
- sess = get_session()
+def get_nova_client(other_creds={}):
+ sess = get_session(other_creds)
return novaclient.Client(get_nova_client_version(), session=sess)
@@ -197,8 +206,8 @@ def get_cinder_client_version():
return DEFAULT_API_VERSION
-def get_cinder_client():
- sess = get_session()
+def get_cinder_client(other_creds={}):
+ sess = get_session(other_creds)
return cinderclient.Client(get_cinder_client_version(), session=sess)
@@ -211,8 +220,8 @@ def get_neutron_client_version():
return DEFAULT_API_VERSION
-def get_neutron_client():
- sess = get_session()
+def get_neutron_client(other_creds={}):
+ sess = get_session(other_creds)
return neutronclient.Client(get_neutron_client_version(), session=sess)
@@ -224,8 +233,8 @@ def get_glance_client_version():
return DEFAULT_API_VERSION
-def get_glance_client():
- sess = get_session()
+def get_glance_client(other_creds={}):
+ sess = get_session(other_creds)
return glanceclient.Client(get_glance_client_version(), session=sess)
@@ -1244,7 +1253,10 @@ def delete_volume_type(cinder_client, volume_type):
# *********************************************
def get_tenants(keystone_client):
try:
- tenants = keystone_client.tenants.list()
+ if is_keystone_v3():
+ tenants = keystone_client.projects.list()
+ else:
+ tenants = keystone_client.tenants.list()
return tenants
except Exception, e:
logger.error("Error [get_tenants(keystone_client)]: %s" % e)
@@ -1261,7 +1273,7 @@ def get_users(keystone_client):
def get_tenant_id(keystone_client, tenant_name):
- tenants = keystone_client.tenants.list()
+ tenants = get_tenants(keystone_client)
id = ''
for t in tenants:
if t.name == tenant_name:
@@ -1271,7 +1283,7 @@ def get_tenant_id(keystone_client, tenant_name):
def get_user_id(keystone_client, user_name):
- users = keystone_client.users.list()
+ users = get_users(keystone_client)
id = ''
for u in users:
if u.name == user_name:
@@ -1292,9 +1304,16 @@ def get_role_id(keystone_client, role_name):
def create_tenant(keystone_client, tenant_name, tenant_description):
try:
- tenant = keystone_client.tenants.create(tenant_name,
- tenant_description,
- enabled=True)
+ if is_keystone_v3():
+ tenant = keystone_client.projects.create(
+ name=tenant_name,
+ description=tenant_description,
+ domain="default",
+ enabled=True)
+ else:
+ tenant = keystone_client.tenants.create(tenant_name,
+ tenant_description,
+ enabled=True)
return tenant.id
except Exception, e:
logger.error("Error [create_tenant(keystone_client, '%s', '%s')]: %s"
@@ -1305,9 +1324,18 @@ def create_tenant(keystone_client, tenant_name, tenant_description):
def create_user(keystone_client, user_name, user_password,
user_email, tenant_id):
try:
- user = keystone_client.users.create(user_name, user_password,
- user_email, tenant_id,
- enabled=True)
+ if is_keystone_v3():
+ user = keystone_client.users.create(name=user_name,
+ password=user_password,
+ email=user_email,
+ project_id=tenant_id,
+ enabled=True)
+ else:
+ user = keystone_client.users.create(user_name,
+ user_password,
+ user_email,
+ tenant_id,
+ enabled=True)
return user.id
except Exception, e:
logger.error("Error [create_user(keystone_client, '%s', '%s', '%s'"
@@ -1318,7 +1346,12 @@ def create_user(keystone_client, user_name, user_password,
def add_role_user(keystone_client, user_id, role_id, tenant_id):
try:
- keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
+ if is_keystone_v3():
+ keystone_client.roles.grant(role=role_id,
+ user=user_id,
+ project=tenant_id)
+ else:
+ keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
return True
except Exception, e:
logger.error("Error [add_role_user(keystone_client, '%s', '%s'"
@@ -1328,7 +1361,10 @@ def add_role_user(keystone_client, user_id, role_id, tenant_id):
def delete_tenant(keystone_client, tenant_id):
try:
- keystone_client.tenants.delete(tenant_id)
+ if is_keystone_v3():
+ keystone_client.projects.delete(tenant_id)
+ else:
+ keystone_client.tenants.delete(tenant_id)
return True
except Exception, e:
logger.error("Error [delete_tenant(keystone_client, '%s')]: %s"
diff --git a/run_unit_tests.sh b/run_unit_tests.sh
index 71d21c9db..79d05d3d1 100755
--- a/run_unit_tests.sh
+++ b/run_unit_tests.sh
@@ -2,28 +2,6 @@
set -o errexit
set -o pipefail
-# ******************************
-# prepare the env for the tests
-# ******************************
-# clean useless results dir
-# should be done at the end
-# but in case of crash during unit test
-# clean it anyway
-if [ -d "/home/opnfv/functest/results" ]
-then
- sudo rm -rf /home/opnfv/functest
-fi
-
-# TODO clean that...
-# Create log dir if needed
-# log shall be disabled during unit tests
-# fix to be done in Logger
-echo "Create dummy log file...."
-sudo mkdir -p /home/opnfv/functest/results/odl
-sudo touch /home/opnfv/functest/results/functest.log
-sudo touch /home/opnfv/functest/results/odl/stdout.txt
-sudo chmod -Rf a+rw /home/opnfv
-
# Either Workspace is set (CI)
if [ -z $WORKSPACE ]
then
@@ -54,8 +32,10 @@ nosetests --with-xunit \
--with-coverage \
--cover-erase \
--cover-tests \
+ --cover-package=functest.cli \
--cover-package=functest.core.testcase_base \
--cover-package=functest.opnfv_tests.sdn.odl.odl \
+ --cover-package=functest.utils \
--cover-xml \
--cover-html \
functest/tests/unit
@@ -63,13 +43,4 @@ rc=$?
deactivate
-# *******
-# clean
-# *******
-# Clean useless logs
-if [ -d "/home/opnfv/functest/results" ]
-then
- sudo rm -rf /home/opnfv/functest/results
-fi
-
exit $rc
diff --git a/test-requirements.txt b/test-requirements.txt
index 8be8e2033..2bf297ba8 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -5,6 +5,7 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
#
+click==6.6
coverage==4.1
dnspython==1.15.0
gitpython==1.0.1
@@ -15,9 +16,10 @@ python-congressclient==1.5.0
python-keystoneclient==3.5.0
python-neutronclient==6.0.0
python-openstackclient==2.3.0
+python-tackerclient==0.7.0
pyyaml==3.10
requests==2.8.0
robotframework==2.9.1
robotframework-requests==0.3.8
robotframework-sshlibrary==2.1.1
-virtualenv==15.1.0 \ No newline at end of file
+virtualenv==15.1.0