Merge "Reverted the file permission"
authorHelen Yao <yaohelan@huawei.com>
Sun, 22 Jan 2017 02:39:53 +0000 (02:39 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Sun, 22 Jan 2017 02:39:53 +0000 (02:39 +0000)
70 files changed:
.coveragerc [new file with mode: 0644]
INFO
docker/Dockerfile
functest/ci/check_os.sh
functest/ci/config_functest.yaml
functest/ci/exec_test.sh
functest/ci/generate_report.py
functest/ci/prepare_env.py
functest/ci/run_tests.py
functest/ci/testcases.yaml
functest/cli/cli_base.py
functest/cli/commands/cli_env.py
functest/cli/commands/cli_os.py
functest/cli/commands/cli_testcase.py
functest/cli/commands/cli_tier.py
functest/core/feature_base.py
functest/core/testcase_base.py
functest/core/vnf_base.py [new file with mode: 0644]
functest/opnfv_tests/features/copper.py
functest/opnfv_tests/features/domino.py
functest/opnfv_tests/features/odl_sfc.py
functest/opnfv_tests/features/sdnvpn.py
functest/opnfv_tests/mano/orchestra.py [new file with mode: 0755]
functest/opnfv_tests/openstack/examples/create_instance_and_ip.py
functest/opnfv_tests/openstack/healthcheck/healthcheck.sh
functest/opnfv_tests/openstack/rally/run_rally-cert.py
functest/opnfv_tests/openstack/snaps/api_check.py
functest/opnfv_tests/openstack/snaps/connection_check.py
functest/opnfv_tests/openstack/snaps/smoke.py
functest/opnfv_tests/openstack/snaps/snaps_utils.py
functest/opnfv_tests/openstack/tempest/conf_utils.py
functest/opnfv_tests/openstack/tempest/tempest.py
functest/opnfv_tests/openstack/vping/vping_base.py
functest/opnfv_tests/sdn/odl/odl.py
functest/opnfv_tests/sdn/onos/teston/onos.py
functest/opnfv_tests/vnf/aaa/__init__.py [new file with mode: 0644]
functest/opnfv_tests/vnf/aaa/aaa.py [new file with mode: 0644]
functest/opnfv_tests/vnf/ims/__init__.py [new file with mode: 0644]
functest/opnfv_tests/vnf/ims/cloudify_ims.py [new file with mode: 0644]
functest/opnfv_tests/vnf/ims/opera_ims.py [new file with mode: 0644]
functest/opnfv_tests/vnf/ims/orchestra_ims.py [new file with mode: 0644]
functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py [moved from functest/opnfv_tests/vnf/ims/orchestrator.py with 100% similarity]
functest/opnfv_tests/vnf/ims/vims.py [deleted file]
functest/tests/unit/cli/__init__.py [new file with mode: 0644]
functest/tests/unit/cli/commands/__init__.py [new file with mode: 0644]
functest/tests/unit/cli/commands/test_cli_env.py [new file with mode: 0644]
functest/tests/unit/cli/commands/test_cli_os.py [new file with mode: 0644]
functest/tests/unit/cli/commands/test_cli_testcase.py [new file with mode: 0644]
functest/tests/unit/cli/commands/test_cli_tier.py [new file with mode: 0644]
functest/tests/unit/cli/test_cli_base.py [new file with mode: 0644]
functest/tests/unit/core/test_testcase_base.py
functest/tests/unit/core/test_vnf_base.py [new file with mode: 0644]
functest/tests/unit/odl/test_odl.py
functest/tests/unit/test_utils.py [new file with mode: 0644]
functest/tests/unit/utils/test_functest_utils.py [new file with mode: 0644]
functest/tests/unit/utils/test_openstack_clean.py [new file with mode: 0644]
functest/tests/unit/utils/test_openstack_snapshot.py [new file with mode: 0644]
functest/tests/unit/utils/test_openstack_tacker.py [new file with mode: 0644]
functest/tests/unit/utils/test_openstack_utils.py [new file with mode: 0644]
functest/tests/unit/utils/test_utils.py [deleted file]
functest/utils/config.py
functest/utils/env.py
functest/utils/functest_constants.py
functest/utils/functest_logger.py
functest/utils/functest_utils.py
functest/utils/openstack_clean.py
functest/utils/openstack_snapshot.py
functest/utils/openstack_utils.py
run_unit_tests.sh
test-requirements.txt

diff --git a/.coveragerc b/.coveragerc
new file mode 100644 (file)
index 0000000..fe258c6
--- /dev/null
@@ -0,0 +1,3 @@
+[report]
+exclude_lines =
+    if __name__ == .__main__.:
diff --git a/INFO b/INFO
index 07145bd..6f8963e 100644 (file)
--- 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
index 5105fbb..dce657e 100644 (file)
@@ -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 -' \
index 053796d..e247102 100755 (executable)
@@ -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..."
index 11ff7fd..25be172 100755 (executable)
@@ -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
index 2b4cd8b..7c96d69 100755 (executable)
@@ -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
index a90bc55..89d8fc6 100755 (executable)
@@ -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')
index 41cbbe0..74c751a 100755 (executable)
 #
 
 
+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)
index 557ba08..a5f1ab9 100755 (executable)
@@ -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)
index 6f57c70..ede0828 100755 (executable)
@@ -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'
index 3b14fa3..cc697ed 100644 (file)
@@ -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)
index 9f793e7..9423631 100644 (file)
@@ -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
index bb85921..aeb3497 100644 (file)
@@ -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 "
index 70a77a1..b656624 100644 (file)
@@ -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)
index 9da5107..b9d25b6 100644 (file)
@@ -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)
index 01a27f3..873e21d 100644 (file)
@@ -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)
index 838b639..ec46bc6 100644 (file)
@@ -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 (file)
index 0000000..4d01985
--- /dev/null
@@ -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)
index 8d5393c..a10364e 100755 (executable)
@@ -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
index 341648f..b36220f 100755 (executable)
 # 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
index b194b28..3b68d42 100644 (file)
@@ -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
index 451299e..1919a03 100755 (executable)
@@ -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 (executable)
index 0000000..fd5e40d
--- /dev/null
@@ -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)
index 4a9ff71..b440086 100755 (executable)
@@ -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():
index e27cf4b..57aa0c7 100755 (executable)
@@ -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."
 
index 6d8f016..b02fd42 100755 (executable)
@@ -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)
index 2788920..17d05b9 100644 (file)
@@ -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)
index c2f5b10..11f8ad0 100644 (file)
@@ -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)
index f66c17f..83eb660 100644 (file)
@@ -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)
index a25ad3e..4ea1a04 100644 (file)
@@ -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)
index 38b97e7..67b5279 100644 (file)
@@ -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")
index ec0ca76..0014b71 100644 (file)
@@ -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)
 
 
index e467dd9..8285d93 100644 (file)
@@ -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
index 0905e55..339c305 100755 (executable)
@@ -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)
index 300f56d..213bdb7 100755 (executable)
@@ -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 (file)
index 0000000..e69de29
diff --git a/functest/opnfv_tests/vnf/aaa/aaa.py b/functest/opnfv_tests/vnf/aaa/aaa.py
new file mode 100644 (file)
index 0000000..f1c265f
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
new file mode 100644 (file)
index 0000000..13a5af4
--- /dev/null
@@ -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 (file)
index 0000000..073a56c
--- /dev/null
@@ -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 (file)
index 0000000..28f37f0
--- /dev/null
@@ -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/vims.py b/functest/opnfv_tests/vnf/ims/vims.py
deleted file mode 100755 (executable)
index fe888b6..0000000
+++ /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 (file)
index 0000000..e69de29
diff --git a/functest/tests/unit/cli/commands/__init__.py b/functest/tests/unit/cli/commands/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
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 (file)
index 0000000..f70761d
--- /dev/null
@@ -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 (file)
index 0000000..f0e58c6
--- /dev/null
@@ -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 (file)
index 0000000..39c8139
--- /dev/null
@@ -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 (file)
index 0000000..802359f
--- /dev/null
@@ -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 (file)
index 0000000..fe065c2
--- /dev/null
@@ -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)
index b7c81d8..8df524b 100644 (file)
@@ -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 (file)
index 0000000..e27f216
--- /dev/null
@@ -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)
index d8c7f84..59ab2c6 100644 (file)
@@ -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 (file)
index 0000000..e171db0
--- /dev/null
@@ -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 (file)
index 0000000..c4b5666
--- /dev/null
@@ -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 (file)
index 0000000..28eab4f
--- /dev/null
@@ -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 (file)
index 0000000..52744db
--- /dev/null
@@ -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 (file)
index 0000000..a8330c0
--- /dev/null
@@ -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 (file)
index 0000000..0f51041
--- /dev/null
@@ -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 (file)
index 8b6c5e1..0000000
+++ /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)
index 4cee634..84166c1 100644 (file)
@@ -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()
index b6af767..fa5245f 100644 (file)
@@ -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()
index 2664ace..7fb03e8 100644 (file)
@@ -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')
index b154f56..c0fba08 100644 (file)
@@ -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')
index b1e4d3c..2bf87a0 100644 (file)
@@ -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)
index c08568b..15a8f33 100755 (executable)
 #
 
 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__':
index 5b50ffa..e64030f 100755 (executable)
 # 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))
index ec78412..64f1850 100755 (executable)
@@ -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"
index 71d21c9..79d05d3 100755 (executable)
@@ -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
index 8be8e20..2bf297b 100644 (file)
@@ -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