summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--INFO7
-rw-r--r--docker/Dockerfile12
-rw-r--r--docker/docker_remote_api/docs/TLS-intro.rst214
-rwxr-xr-x[-rw-r--r--]docker/docker_remote_api/enable_remote_api.sh102
-rw-r--r--docs/internship/security_group/index.rst70
-rw-r--r--docs/internship/testapi_evolution/index.rst70
-rw-r--r--docs/internship/unit_tests/index.rst70
-rw-r--r--docs/internship/vnf_catalog/index.rst170
-rwxr-xr-xfunctest/ci/config_functest.yaml422
-rwxr-xr-xfunctest/ci/exec_test.sh39
-rwxr-xr-xfunctest/ci/generate_report.py54
-rwxr-xr-xfunctest/ci/prepare_env.py123
-rwxr-xr-x[-rw-r--r--]functest/ci/run_tests.py45
-rwxr-xr-xfunctest/ci/testcases.yaml23
-rw-r--r--functest/cli/cli_base.py14
-rw-r--r--functest/cli/commands/cli_env.py72
-rw-r--r--functest/cli/commands/cli_os.py45
-rw-r--r--functest/cli/commands/cli_testcase.py32
-rw-r--r--functest/cli/commands/cli_tier.py29
-rw-r--r--functest/core/feature_base.py10
-rwxr-xr-x[-rw-r--r--]functest/core/pytest_suite_runner.py4
-rw-r--r--functest/core/testcase_base.py10
-rwxr-xr-xfunctest/opnfv_tests/features/copper.py72
-rw-r--r--functest/opnfv_tests/features/odl_sfc.py20
-rwxr-xr-x[-rw-r--r--]functest/opnfv_tests/features/sdnvpn.py70
-rwxr-xr-xfunctest/opnfv_tests/openstack/examples/create_instance_and_ip.py49
-rwxr-xr-xfunctest/opnfv_tests/openstack/rally/run_rally-cert.py33
-rw-r--r--functest/opnfv_tests/openstack/snaps/api_check.py19
-rw-r--r--functest/opnfv_tests/openstack/snaps/connection_check.py19
-rw-r--r--functest/opnfv_tests/openstack/snaps/smoke.py23
-rw-r--r--functest/opnfv_tests/openstack/snaps/snaps_utils.py5
-rw-r--r--functest/opnfv_tests/openstack/tempest/__init__.py0
-rw-r--r--functest/opnfv_tests/openstack/tempest/conf_utils.py190
-rwxr-xr-xfunctest/opnfv_tests/openstack/tempest/gen_tempest_conf.py126
-rwxr-xr-xfunctest/opnfv_tests/openstack/tempest/run_tempest.py451
-rw-r--r--functest/opnfv_tests/openstack/tempest/tempest.py331
-rwxr-xr-x[-rw-r--r--]functest/opnfv_tests/openstack/vping/vping_base.py43
-rwxr-xr-x[-rw-r--r--]functest/opnfv_tests/openstack/vping/vping_ssh.py6
-rwxr-xr-x[-rw-r--r--]functest/opnfv_tests/openstack/vping/vping_userdata.py0
-rwxr-xr-xfunctest/opnfv_tests/sdn/odl/odl.py51
-rw-r--r--functest/opnfv_tests/sdn/onos/sfc/sfc_onos.py2
-rwxr-xr-xfunctest/opnfv_tests/vnf/ims/vims.py51
-rw-r--r--functest/tests/unit/cli/__init__.py0
-rw-r--r--functest/tests/unit/cli/commands/__init__.py0
-rw-r--r--functest/tests/unit/cli/commands/test_cli_env.py130
-rw-r--r--functest/tests/unit/cli/commands/test_cli_os.py238
-rw-r--r--functest/tests/unit/cli/commands/test_cli_testcase.py103
-rw-r--r--functest/tests/unit/cli/commands/test_cli_tier.py130
-rw-r--r--functest/tests/unit/cli/test_cli_base.py138
-rw-r--r--functest/tests/unit/core/test_testcase_base.py19
-rw-r--r--functest/tests/unit/odl/test_odl.py140
-rw-r--r--functest/tests/unit/test_utils.py23
-rw-r--r--functest/tests/unit/utils/test_functest_utils.py599
-rw-r--r--functest/tests/unit/utils/test_utils.py45
-rw-r--r--functest/utils/config.py35
-rw-r--r--functest/utils/constants.py20
-rw-r--r--functest/utils/env.py41
-rw-r--r--functest/utils/functest_constants.py77
-rw-r--r--functest/utils/functest_utils.py25
-rwxr-xr-xfunctest/utils/openstack_clean.py12
-rwxr-xr-xfunctest/utils/openstack_snapshot.py9
-rwxr-xr-x[-rw-r--r--]functest/utils/openstack_tacker.py2
-rwxr-xr-xfunctest/utils/openstack_utils.py356
-rwxr-xr-xrun_unit_tests.sh20
-rw-r--r--setup.py50
-rwxr-xr-xtest-requirements.txt3
66 files changed, 3554 insertions, 1859 deletions
diff --git a/INFO b/INFO
index 1f34d8cdf..6f8963e76 100644
--- a/INFO
+++ b/INFO
@@ -3,15 +3,16 @@ Project Creation Date: January 20, 2015
Project Category: Integration & Testing
Lifecycle State: Incubation
Primary Contact: Jose Lausuch (jose.lausuch@ericsson.com)
-Project Lead: Jose lausuch (jose.lausuch@ericsson.com)
+Project Lead: Jose lausuch (jose.lausuch@ericsson.com)
Jira Project Name: Base System Functionality Testing Project
Jira Project Prefix: FUNCTEST
Mailing list tag: [functest]
-IRC: Server:freenode.net Channel:#opnfv-testperf
+IRC: Server:freenode.net Channel:#opnfv-functest
Repository: functest
Committers:
-serena.feng.711@gmail.com
+yaohelan@huawei.com
+feng.xiaowei@zte.com.cn
ollivier.cedric@gmail.com
jose.lausuch@ericsson.com
morgan.richomme@orange.com
diff --git a/docker/Dockerfile b/docker/Dockerfile
index f76dd7979..5105fbbd1 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -32,7 +32,7 @@ LABEL version="0.1" description="OPNFV Functest Docker container"
ARG BRANCH=master
ARG TEMPEST_TAG=12.2.0
ARG RALLY_TAG=0.7.0
-ARG ODL_TAG=release/beryllium-sr3
+ARG ODL_TAG=release/beryllium-sr4
ARG OPENSTACK_TAG=stable/mitaka
ARG KINGBIRD_TAG=0.2.2
ARG VIMS_TAG=stable
@@ -125,7 +125,7 @@ RUN pip install -r ${REPOS_DIR}/rally/requirements.txt
RUN pip install -r ${REPOS_DIR}/tempest/requirements.txt
RUN find ${FUNCTEST_REPO_DIR} -name "*.py" \
- -not -path *unit_tests* |xargs grep __main__ |cut -d\: -f 1 |xargs chmod -c 755 \
+ -not -path "*tests/unit*" |xargs grep __main__ |cut -d\: -f 1 |xargs chmod -c 755 \
&& find ${FUNCTEST_REPO_DIR} -name "*.sh" |xargs grep \#\! |cut -d\: -f 1 |xargs chmod -c 755
RUN /bin/bash ${REPOS_DIR}/parser/tests/parser_install.sh ${REPOS_DIR}
@@ -142,7 +142,13 @@ RUN curl -L https://get.rvm.io | bash -s stable
RUN git clone --depth 1 https://gerrit.cablelabs.com/snaps-provisioning ${REPOS_DIR}/snaps
RUN pip install -e ${REPOS_DIR}/snaps/
-RUN /bin/bash -c ". ${REPOS_DIR}/sfc/tests/functest/odl-sfc/tacker_client_install.sh"
+# SFC integration
+RUN /bin/bash -c ". ${REPOS_DIR}/sfc/sfc/tests/functest/setup_scripts/tacker_client_install.sh"
+RUN cd ${REPOS_DIR}/sfc && pip install .
+
+# SDNVPN integration
+RUN cd ${REPOS_DIR}/sdnvpn && pip install .
+
RUN cd ${REPOS_DIR}/bgpvpn && pip install .
#RUN cd ${REPOS_DIR}/kingbird && pip install -e .
RUN cd ${REPOS_DIR}/moon/moonclient/ && python setup.py install
diff --git a/docker/docker_remote_api/docs/TLS-intro.rst b/docker/docker_remote_api/docs/TLS-intro.rst
index 934f99a8b..44fdd4aed 100644
--- a/docker/docker_remote_api/docs/TLS-intro.rst
+++ b/docker/docker_remote_api/docs/TLS-intro.rst
@@ -1,107 +1,107 @@
-Encrypt the docker remote API via TLS for Ubuntu and CentOS
-
-[Introduction]
-The Docker daemon can listen to Docker Remote API requests via three types of
-Socket: unix, tcp and fd. By default, a unix domain socket (or IPC socket) is
-created at /var/run/docker.sock, requiring either root permission, or docker
-group membership.
-
-Port 2375 is conventionally used for un-encrypted communition with Docker daemon
-remotely, where docker server can be accessed by any docker client via tcp socket
-in local area network. You can listen to port 2375 on all network interfaces with
--H tcp://0.0.0.0:2375, where 0.0.0.0 means any available IP address on host, and
-tcp://0.0.0.0:2375 indicates that port 2375 is listened on any IP of daemon host.
-If we want to make docker server open on the Internet via TCP port, and only trusted
-clients have the right to access the docker server in a safe manner, port 2376 for
-encrypted communication with the daemon should be listened. It can be achieved to
-create certificate and distribute it to the trusted clients.
-
-Through creating self-signed certificate, and using --tlsverify command when running
-Docker daemon, Docker daemon opens the TLS authentication. Thus only the clients
-with related private key files can have access to the Docker daemon's server. As
-long as the key files for encryption are secure between docker server and client,
-the Docker daemon can keep secure.
-In summary,
-Firstly we should create docker server certificate and related key files, which
-are distributed to the trusted clients.
-Then the clients with related key files can access docker server.
-
-[Steps]
-1.0. Create a CA, server and client keys with OpenSSL.
- OpenSSL is used to generate certificate, and can be installed as follows.
- apt-get install openssl openssl-devel
-
-1.1 First generate CA private and public keys.
- openssl genrsa -aes256 -out ca-key.pem 4096
- openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
-
- You are about to be asked to enter information that will be incorporated
- into your certificate request, where the instance of $HOST should be replaced
- with the DNS name of your Docker daemon's host, here the DNS name of my Docker
- daemon is ly.
- Common Name (e.g. server FQDN or YOUR name) []:$HOST
-
-1.2 Now we have a CA (ca-key.pem and ca.pem), you can create a server key and
-certificate signing request.
- openssl genrsa -out server-key.pem 4096
- openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
-
-1.3 Sign the public key with our CA.
- TLS connections can be made via IP address as well as DNS name, they need to be
- specified when creating the certificate.
-
- echo subjectAltName = IP:172.16.10.121,IP:127.0.0.1 > extfile.cnf
- openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
- -CAcreateserial -out server-cert.pem -extfile extfile.cnf
-
-1.4 For client authentication, create a client key and certificate signing request.
- openssl genrsa -out key.pem 4096
- openssl req -subj '/CN=client' -new -key key.pem -out client.csr
-
-1.5 To make the key suitable for client authentication, create an extensions config file.
- echo extendedKeyUsage = clientAuth > extfile.cnf
-
-1.6 Sign the public key and after generating cert.pem and server-cert.pem, two certificate
- signing requests can be removed.
- openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
- -CAcreateserial -out cert.pem -extfile extfile.cnf
-
-1.7 In order to protect your keys from accidental damage, you may change file modes to
- be only readable.
- chmod -v 0400 ca-key.pem key.pem server-key.pem
- chmod -v 0444 ca.pem server-cert.pem cert.pem
-
-1.8 Build docker server
- dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem \
- -H=0.0.0.0:2376
- Then, it can be seen from the command 'netstat -ntlp' that port 2376 has been listened
- and the Docker daemon only accept connections from clients providing a certificate
- trusted by our CA.
-
-1.9 Distribute the keys to the client
- scp /etc/docker/ca.pem wwl@172.16.10.121:/etc/docker
- scp /etc/docker/cert.pem wwl@172.16.10.121:/etc/docker
- scp /etc/docker/key.pem wwl@172.16.10.121:/etc/docker
- Where, wwl and 172.16.10.121 is the username and IP of the client respectively.
- And the password of the client is needed when you distribute the keys to the client.
-
-1.10 To access Docker daemon from the client via keys.
- docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \
- -H=$HOST:2376 version
-
- Then we can operate docker in the Docker daemon from the client vis keys, for example:
- 1) create container from the client
- docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 run -d \
- -it --name w1 grafana/grafana
- 2) list containers from the client
- docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 pa -a
- 3) stop/start containers from the client
- docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 stop w1
- docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 start w1
-
-
-
-
-
-
-
+Encrypt the docker remote API via TLS for Ubuntu and CentOS
+
+[Introduction]
+The Docker daemon can listen to Docker Remote API requests via three types of
+Socket: unix, tcp and fd. By default, a unix domain socket (or IPC socket) is
+created at /var/run/docker.sock, requiring either root permission, or docker
+group membership.
+
+Port 2375 is conventionally used for un-encrypted communition with Docker daemon
+remotely, where docker server can be accessed by any docker client via tcp socket
+in local area network. You can listen to port 2375 on all network interfaces with
+-H tcp://0.0.0.0:2375, where 0.0.0.0 means any available IP address on host, and
+tcp://0.0.0.0:2375 indicates that port 2375 is listened on any IP of daemon host.
+If we want to make docker server open on the Internet via TCP port, and only trusted
+clients have the right to access the docker server in a safe manner, port 2376 for
+encrypted communication with the daemon should be listened. It can be achieved to
+create certificate and distribute it to the trusted clients.
+
+Through creating self-signed certificate, and using --tlsverify command when running
+Docker daemon, Docker daemon opens the TLS authentication. Thus only the clients
+with related private key files can have access to the Docker daemon's server. As
+long as the key files for encryption are secure between docker server and client,
+the Docker daemon can keep secure.
+In summary,
+Firstly we should create docker server certificate and related key files, which
+are distributed to the trusted clients.
+Then the clients with related key files can access docker server.
+
+[Steps]
+1.0. Create a CA, server and client keys with OpenSSL.
+ OpenSSL is used to generate certificate, and can be installed as follows.
+ apt-get install openssl openssl-devel
+
+1.1 First generate CA private and public keys.
+ openssl genrsa -aes256 -out ca-key.pem 4096
+ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
+
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request, where the instance of $HOST should be replaced
+ with the DNS name of your Docker daemon's host, here the DNS name of my Docker
+ daemon is ly.
+ Common Name (e.g. server FQDN or YOUR name) []:$HOST
+
+1.2 Now we have a CA (ca-key.pem and ca.pem), you can create a server key and
+certificate signing request.
+ openssl genrsa -out server-key.pem 4096
+ openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
+
+1.3 Sign the public key with our CA.
+ TLS connections can be made via IP address as well as DNS name, they need to be
+ specified when creating the certificate.
+
+ echo subjectAltName = IP:172.16.10.121,IP:127.0.0.1 > extfile.cnf
+ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
+ -CAcreateserial -out server-cert.pem -extfile extfile.cnf
+
+1.4 For client authentication, create a client key and certificate signing request.
+ openssl genrsa -out key.pem 4096
+ openssl req -subj '/CN=client' -new -key key.pem -out client.csr
+
+1.5 To make the key suitable for client authentication, create an extensions config file.
+ echo extendedKeyUsage = clientAuth > extfile.cnf
+
+1.6 Sign the public key and after generating cert.pem and server-cert.pem, two certificate
+ signing requests can be removed.
+ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
+ -CAcreateserial -out cert.pem -extfile extfile.cnf
+
+1.7 In order to protect your keys from accidental damage, you may change file modes to
+ be only readable.
+ chmod -v 0400 ca-key.pem key.pem server-key.pem
+ chmod -v 0444 ca.pem server-cert.pem cert.pem
+
+1.8 Build docker server
+ dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem \
+ -H=0.0.0.0:2376
+ Then, it can be seen from the command 'netstat -ntlp' that port 2376 has been listened
+ and the Docker daemon only accept connections from clients providing a certificate
+ trusted by our CA.
+
+1.9 Distribute the keys to the client
+ scp /etc/docker/ca.pem wwl@172.16.10.121:/etc/docker
+ scp /etc/docker/cert.pem wwl@172.16.10.121:/etc/docker
+ scp /etc/docker/key.pem wwl@172.16.10.121:/etc/docker
+ Where, wwl and 172.16.10.121 is the username and IP of the client respectively.
+ And the password of the client is needed when you distribute the keys to the client.
+
+1.10 To access Docker daemon from the client via keys.
+ docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \
+ -H=$HOST:2376 version
+
+ Then we can operate docker in the Docker daemon from the client vis keys, for example:
+ 1) create container from the client
+ docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 run -d \
+ -it --name w1 grafana/grafana
+ 2) list containers from the client
+ docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 pa -a
+ 3) stop/start containers from the client
+ docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 stop w1
+ docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=ly:2376 start w1
+
+
+
+
+
+
+
diff --git a/docker/docker_remote_api/enable_remote_api.sh b/docker/docker_remote_api/enable_remote_api.sh
index 6867eeddf..76e59b850 100644..100755
--- a/docker/docker_remote_api/enable_remote_api.sh
+++ b/docker/docker_remote_api/enable_remote_api.sh
@@ -1,51 +1,51 @@
-#!/bin/bash
-# SPDX-license-identifier: Apache-2.0
-
-# ******************************
-# Script to update the docker host configuration
-# to enable Docker Remote API
-# ******************************
-
-if [ -f /etc/lsb-release ]; then
- #tested on ubuntu 14.04 and 16.04
- if grep -q "#DOCKER_OPTS=" "/etc/default/docker"; then
- cp /etc/default/docker /etc/default/docker.bak
- sed -i 's/^#DOCKER_OPTS.*$/DOCKER_OPTS=\"-H unix:\/\/\/var\/run\/docker.sock -H tcp:\/\/0.0.0.0:2375\"/g' /etc/default/docker
- else
- echo DOCKER_OPTS=\"-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375\" >> /etc/default/docker
- fi
- service docker restart
- #docker start $(docker ps -aq)
-elif [ -f /etc/system-release ]; then
- #tested on centos 7.2
- if grep -q "ExecStart=\/usr\/bin\/docker-current daemon" "/lib/systemd/system/docker.service"; then
- cp /lib/systemd/system/docker.service /lib/systemd/system/docker.service.bak
- sed -i 's/^ExecStart=.*$/ExecStart=\/usr\/bin\/docker daemon -H tcp:\/\/0.0.0.0:2375 -H unix:\/\/\/var\/run\/docker.sock \\/g' /lib/systemd/system/docker.service
- systemctl daemon-reload
- systemctl restart docker
- else
- echo "to be implemented"
- fi
-else
- echo "OS is not supported"
-fi
-
-# Issue Note for Ubuntu
-# 1. If the configuration of the file /etc/default/docker does not take effect after restarting docker service,
-# you may try to modify /lib/systemd/system/docker.service
-# commands:
-# cp /lib/systemd/system/docker.service /lib/systemd/system/docker.service.bak
-# sed -i '/^ExecStart/i\EnvironmentFile=-/etc/default/docker' /lib/systemd/system/docker.service
-# sed -i '/ExecStart=\/usr\/bin\/dockerd/{;s/$/ \$DOCKER_OPTS/}' /lib/systemd/system/docker.service
-# systemctl daemon-reload
-# service docker restart
-# 2. Systemd is a system and session manager for Linux, where systemctl is one tool for systemd to view and control systemd.
-# If the file /lib/systemd/system/docker.service is modified, systemd has to be reloaded to scan new or changed units.
-# 1) systemd and related packages are available on the PPA. To use the PPA, first add it to your software sources list as follows.
-# add-apt-repository ppa:pitti/systemd
-# apt-get update
-# 2) system can be installed from the PPS as follows.
-# apt-get install systemd libpam-systemd systemd-ui
-
-
-
+#!/bin/bash
+# SPDX-license-identifier: Apache-2.0
+
+# ******************************
+# Script to update the docker host configuration
+# to enable Docker Remote API
+# ******************************
+
+if [ -f /etc/lsb-release ]; then
+ #tested on ubuntu 14.04 and 16.04
+ if grep -q "#DOCKER_OPTS=" "/etc/default/docker"; then
+ cp /etc/default/docker /etc/default/docker.bak
+ sed -i 's/^#DOCKER_OPTS.*$/DOCKER_OPTS=\"-H unix:\/\/\/var\/run\/docker.sock -H tcp:\/\/0.0.0.0:2375\"/g' /etc/default/docker
+ else
+ echo DOCKER_OPTS=\"-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375\" >> /etc/default/docker
+ fi
+ service docker restart
+ #docker start $(docker ps -aq)
+elif [ -f /etc/system-release ]; then
+ #tested on centos 7.2
+ if grep -q "ExecStart=\/usr\/bin\/docker-current daemon" "/lib/systemd/system/docker.service"; then
+ cp /lib/systemd/system/docker.service /lib/systemd/system/docker.service.bak
+ sed -i 's/^ExecStart=.*$/ExecStart=\/usr\/bin\/docker daemon -H tcp:\/\/0.0.0.0:2375 -H unix:\/\/\/var\/run\/docker.sock \\/g' /lib/systemd/system/docker.service
+ systemctl daemon-reload
+ systemctl restart docker
+ else
+ echo "to be implemented"
+ fi
+else
+ echo "OS is not supported"
+fi
+
+# Issue Note for Ubuntu
+# 1. If the configuration of the file /etc/default/docker does not take effect after restarting docker service,
+# you may try to modify /lib/systemd/system/docker.service
+# commands:
+# cp /lib/systemd/system/docker.service /lib/systemd/system/docker.service.bak
+# sed -i '/^ExecStart/i\EnvironmentFile=-/etc/default/docker' /lib/systemd/system/docker.service
+# sed -i '/ExecStart=\/usr\/bin\/dockerd/{;s/$/ \$DOCKER_OPTS/}' /lib/systemd/system/docker.service
+# systemctl daemon-reload
+# service docker restart
+# 2. Systemd is a system and session manager for Linux, where systemctl is one tool for systemd to view and control systemd.
+# If the file /lib/systemd/system/docker.service is modified, systemd has to be reloaded to scan new or changed units.
+# 1) systemd and related packages are available on the PPA. To use the PPA, first add it to your software sources list as follows.
+# add-apt-repository ppa:pitti/systemd
+# apt-get update
+# 2) system can be installed from the PPS as follows.
+# apt-get install systemd libpam-systemd systemd-ui
+
+
+
diff --git a/docs/internship/security_group/index.rst b/docs/internship/security_group/index.rst
new file mode 100644
index 000000000..d1cdbdd8f
--- /dev/null
+++ b/docs/internship/security_group/index.rst
@@ -0,0 +1,70 @@
+=======
+License
+=======
+
+Functest Docs are licensed under a Creative Commons Attribution 4.0
+International License.
+You should have received a copy of the license along with this.
+If not, see <http://creativecommons.org/licenses/by/4.0/>.
+
+==================================
+Functest Security group test cases
+==================================
+
+Author: Girish Sukhatankar
+mentors: D.Blaisonneau, J.Lausuch, M.Richomme
+
+Abstract
+========
+
+
+Version history
+===============
+
++------------+----------+------------------+------------------------+
+| **Date** | **Ver.** | **Author** | **Comment** |
+| | | | |
++------------+----------+------------------+------------------------+
+| 2016-??-?? | 0.0.1 | Morgan Richomme | Beginning of the |
+| | | (Orange) | Internship |
++------------+----------+------------------+------------------------+
+
+
+Overview:
+=========
+
+
+
+
+Problem Statement:
+------------------
+
+
+
+Curation Phase
+--------------
+
+
+
+
+
+Schedule:
+=========
+
+
+
++--------------------------+------------------------------------------+
+| **Date** | **Comment** |
+| | |
++--------------------------+------------------------------------------+
+| December - January | ........ |
++--------------------------+------------------------------------------+
+| January - february | ........ |
++--------------------------+------------------------------------------+
+
+
+References:
+===========
+
+.. _`[1]` : https://wiki.opnfv.org/display/DEV/Intern+Project%3A+Security+groups+test+case+in+Functest
+
diff --git a/docs/internship/testapi_evolution/index.rst b/docs/internship/testapi_evolution/index.rst
new file mode 100644
index 000000000..f2583e2f0
--- /dev/null
+++ b/docs/internship/testapi_evolution/index.rst
@@ -0,0 +1,70 @@
+=======
+License
+=======
+
+Functest Docs are licensed under a Creative Commons Attribution 4.0
+International License.
+You should have received a copy of the license along with this.
+If not, see <http://creativecommons.org/licenses/by/4.0/>.
+
+==================
+Test API evolution
+==================
+
+Author: Rohit Sakala
+Mentors: S. Feng, J.Lausuch, M.Richomme
+
+Abstract
+========
+
+
+Version history
+===============
+
++------------+----------+------------------+------------------------+
+| **Date** | **Ver.** | **Author** | **Comment** |
+| | | | |
++------------+----------+------------------+------------------------+
+| 2016-??-?? | 0.0.1 | Morgan Richomme | Beginning of the |
+| | | (Orange) | Internship |
++------------+----------+------------------+------------------------+
+
+
+Overview:
+=========
+
+
+
+
+Problem Statement:
+------------------
+
+
+
+Curation Phase
+--------------
+
+
+
+
+
+Schedule:
+=========
+
+
+
++--------------------------+------------------------------------------+
+| **Date** | **Comment** |
+| | |
++--------------------------+------------------------------------------+
+| December - January | ........ |
++--------------------------+------------------------------------------+
+| January - february | ........ |
++--------------------------+------------------------------------------+
+
+
+References:
+===========
+
+.. _`[1]` : https://wiki.opnfv.org/display/DEV/Intern+Project%3A+testapi+evolution
+
diff --git a/docs/internship/unit_tests/index.rst b/docs/internship/unit_tests/index.rst
new file mode 100644
index 000000000..f969aa72d
--- /dev/null
+++ b/docs/internship/unit_tests/index.rst
@@ -0,0 +1,70 @@
+=======
+License
+=======
+
+Functest Docs are licensed under a Creative Commons Attribution 4.0
+International License.
+You should have received a copy of the license along with this.
+If not, see <http://creativecommons.org/licenses/by/4.0/>.
+
+===================
+Functest Unit tests
+===================
+
+Author: Ashish Kumar
+Mentors: H.Yao, J.Lausuch, M.Richomme
+
+Abstract
+========
+
+
+Version history
+===============
+
++------------+----------+------------------+------------------------+
+| **Date** | **Ver.** | **Author** | **Comment** |
+| | | | |
++------------+----------+------------------+------------------------+
+| 2016-??-?? | 0.0.1 | Morgan Richomme | Beginning of the |
+| | | (Orange) | Internship |
++------------+----------+------------------+------------------------+
+
+
+Overview:
+=========
+
+
+
+
+Problem Statement:
+------------------
+
+
+
+Curation Phase
+--------------
+
+
+
+
+
+Schedule:
+=========
+
+
+
++--------------------------+------------------------------------------+
+| **Date** | **Comment** |
+| | |
++--------------------------+------------------------------------------+
+| December - January | ........ |
++--------------------------+------------------------------------------+
+| January - february | ........ |
++--------------------------+------------------------------------------+
+
+
+References:
+===========
+
+.. _`[1]` : https://wiki.opnfv.org/display/DEV/Intern+Project%3A+Functest+unit+tests
+
diff --git a/docs/internship/vnf_catalog/index.rst b/docs/internship/vnf_catalog/index.rst
new file mode 100644
index 000000000..df7633391
--- /dev/null
+++ b/docs/internship/vnf_catalog/index.rst
@@ -0,0 +1,170 @@
+=======
+License
+=======
+
+Functest Docs are licensed under a Creative Commons Attribution 4.0
+International License.
+You should have received a copy of the license along with this.
+If not, see <http://creativecommons.org/licenses/by/4.0/>.
+
+=======================
+Open Source VNF Catalog
+=======================
+
+Author: Kumar Rishabh
+Mentors: B.Souville, M.Richomme, J.Lausuch
+
+Abstract
+========
+
+
+
+Version hissory
+===============
+
++------------+----------+------------------+------------------------+
+| **Date** | **Ver.** | **Author** | **Comment** |
+| | | | |
++------------+----------+------------------+------------------------+
+| 2016-12-12 | 0.0.1 | Morgan Richomme | Beginning of the |
+| | | (Orange) | Internship |
++------------+----------+------------------+------------------------+
+
+
+Overview:
+=========
+
+
+This project aims to create an Open Source catalog for reference and
+classification of Virtual Network Functions (VNFs)s available on
+Internet. The classification method proposed will be in sync with the
+requirements of Telcos active in NFV landscape. The project aims to have
+running web platform similar to [1] by the mid of internship (2nd week
+of March). By the penultimate month of internship I aim to have fully
+functional implementation of an Open Source VNF in functest.
+
+
+Problem Statement:
+------------------
+
+OPNFV aims to be the reference platform for development,
+standardization and integration of Open Source NFV components across
+various Open Source Platforms. It mainly deals with the infrastructure
+through the Network Function Virtualization Infrastructure (NFVI) and
+Virtual Infrastructure manager (VIM). The MANO (Management and
+orchestration) stacks have been introduced recently. VNFs are not
+directly in OPNFV scope, however VNFs are needed to test and qualify the
+infrastructure. In this regard having a common curated Open Source
+Reference VNF catalog would be of immense importance to community.
+
+Since major focus of OPNFV is Telcos, a curated platform targeted from
+industry point of view would be very useful. We plan to divide the
+entire project into three major phases(with some iterative improvements
+and overlaps)
+
+
+Curation Phase
+--------------
+This phase pertains to studying various Open Source VNFs available and
+classification of them based on certain parameters. The parameters that
+I currently have in mind are:
+ * Developer Metrics: These pertain to repo characteristics of VNF under
+ study
+ * Usage Statistics - Activity, Number of Commits, stars
+ * Maturity Statistics - For instance if an NFV community decides code
+ coverage is important for them, it shows the NFV community is serious
+ about taking the project forward
+ * Technical Tagging: These are the tags that pertain to technical
+ characteristics of a VNF
+ * Broad Use Cases - Whether the VNF fits strictly in IaaS, PaaS or
+ SaaS layer or is an hybrid of two/all.
+ * Generic Use Cases - This in my opinion is the broadest
+ classification category. For instance a VNF could be built with a
+ broad idea of powering IOT devices at home or from usage perspective
+ of Telco Operators (vFW, vEPC, vIMS, vCDN, vAAA, vCPE,...).`[2]`_
+ * Fields of Application
+ * Library Status - Whether APIs are standardized, support RESTful
+ services.
+ * Dependency Forwarding Graph - This is pretty complex tagging
+ mechanism. It essentially tries to establish a graph relationship
+ between the VNFs (elementary VNFs are used in Service Function
+ Chaining chains such as Firewall, DPI, content enrichment,..). In my
+ opinion this is useful immensely. This will allow users to go to
+ platform and ask a question like - “I have this X tech stack to
+ support, Y and Z are my use cases, which NFVs should I use to support
+ this.
+ * Visitor Score - Based on `[1]`_ I plan to evolve a visitor score for
+ the platform. This will allow users to score an NFV on certain
+ parameters, may be post comments.
+
+**I plan to use the above three scores and evolve cumulative score which
+will be displayed next to each of the NFV on the platform.**
+
+ * Platform building phase - This will involve erecting a Web Platform
+ which will be similar to this `[1]`_. I am decently familiar with
+ Django and hence I will write the platform in Django. There are two
+ action plans that I have in mind right now. Either I can start writing
+ the platform simultaneously which will help keep track of my progress
+ or I can write the platform after 1.5 - 2 months into the internship.
+ Either way I aim to have the Web Platform ready by March 12.
+
+ * Functest VNF implementation phase - This is the last phase that will
+ involve writing a fully functional implementation of an Open Source VNF
+ into Functest. I will undertake this after I am 3 months into the
+ internship. I have a decent familiarity with python and hence I think
+ it shouldn’t be too difficult. I need to decide how complex the VNFI
+ should undertake this exercise for (e.g. AAA such as free radius sounds
+ relatively easy, vCDN is much more challenging).
+ This will be decided in consent with my mentors.
+
+
+
+
+Schedule:
+=========
+I plan to take this project in 6 months time frame as I want to use it
+as a chance to read more about NFVs in particular and SDN in general
+
+
++--------------------------+------------------------------------------+
+| **Date** | **Comment** |
+| | |
++--------------------------+------------------------------------------+
+| December 12 - January 12 | Study the above mentioned metrics |
+| | Decide which of them are important for |
+| | community (and which are not). |
++--------------------------+------------------------------------------+
+| January 12 - January 27 | Make a database for the above studied |
+| | metrics and evolve it further based on |
+| | Mentors’ input. + associated API |
++--------------------------+------------------------------------------+
+| January 27 - February 5 | Compile the data collected above and make|
+| | it public. Although I can keep everything|
+| | public from the beginning too. My |
+| | rationale of not making the entire data |
+| | public in initial stage as the errors |
+| | caused by me could be misleading for |
+| | developers. |
++--------------------------+------------------------------------------+
+| February 5 - March 5 | Erect the Web Platform and release it |
+| | for restricted group for alpha testing. |
++--------------------------+------------------------------------------+
+| March 5 - March 12 | Make it public. Release it to public for |
+| | beta testing. Fix Bugs. |
++--------------------------+------------------------------------------+
+| March 12 - April 12 | Start working on implementation of an |
+| | Open Source VNF in Functest. |
++--------------------------+------------------------------------------+
+| April 12 - May 12 | I will decided what to do here based on |
+| | discussion with mentors. |
++--------------------------+------------------------------------------+
+
+
+References:
+===========
+
+.. _`[1]` : Openhub: https://www.openhub.net/explore/projects
+
+.. _`[2]` : ETSI NFV White Paper: https://portal.etsi.org/Portals/0/TBpages/NFV/Docs/NFV_White_Paper3.pdf
+
+.. _`[3]` : https://wiki.opnfv.org/display/DEV/Intern+Project%3A+Open+Source+VNF+catalog
diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml
index 0da2bb8f3..15e0d3a1a 100755
--- a/functest/ci/config_functest.yaml
+++ b/functest/ci/config_functest.yaml
@@ -1,211 +1,211 @@
-general:
- directories:
- # Relative to the path where the repo is cloned:
- dir_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
- 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
- dir_repo_rally: /home/opnfv/repos/rally
- dir_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
- 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
- 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
- dir_vIMS_data: /home/opnfv/functest/data/vIMS/
- dir_rally_inst: /home/opnfv/.rally
-
- openstack:
- creds: /home/opnfv/functest/conf/openstack.creds
- snapshot_file: /home/opnfv/functest/conf/openstack_snapshot.yaml
-
- image_name: Cirros-0.3.4
- image_file_name: cirros-0.3.4-x86_64-disk.img
- image_disk_format: qcow2
-
- flavor_name: opnfv_flavor
- flavor_ram: 512
- flavor_disk: 1
- flavor_vcpus: 1
-
- # Private network for functest. Will be created by config_functest.py
- neutron_private_net_name: functest-net
- neutron_private_subnet_name: functest-subnet
- neutron_private_subnet_cidr: 192.168.120.0/24
- neutron_private_subnet_start: 192.168.120.2
- neutron_private_subnet_end: 192.168.120.254
- neutron_private_subnet_gateway: 192.168.120.254
- neutron_router_name: functest-router
-
- functest:
- testcases_yaml: /home/opnfv/repos/functest/functest/ci/testcases.yaml
-
-healthcheck:
- disk_image: /home/opnfv/functest/data/cirros-0.3.4-x86_64-disk.img
- disk_format: qcow2
- wait_time: 60
-
-snaps:
- use_keystone: True
- use_floating_ips: False
-
-vping:
- ping_timeout: 200
- vm_flavor: m1.tiny # adapt to your environment
- 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
-
-onos_sfc:
- image_base_url: http://artifacts.opnfv.org/sfc/demo
- image_name: TestSfcVm
- image_file_name: firewall_block_image.img
-
-tempest:
- identity:
- tenant_name: tempest
- tenant_description: Tenant for Tempest test suite
- user_name: tempest
- user_password: tempest
- validation:
- ssh_timeout: 130
- private_net_name: tempest-net
- private_subnet_name: tempest-subnet
- private_subnet_cidr: 192.168.150.0/24
- router_name: tempest-router
- use_custom_images: False
- use_custom_flavors: False
-
-rally:
- deployment_name: opnfv-rally
- network_name: rally-net
- subnet_name: rally-subnet
- 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
-ONOS:
- general:
- onosbench_username: 'root'
- onosbench_password: 'root'
- onoscli_username: 'root'
- onoscli_password: 'root'
- runtimeout: 300
- environment:
- OCT: '10.20.0.1'
- OC1: '10.20.0.7'
- OC2: '10.20.0.7'
- OC3: '10.20.0.7'
- OCN: '10.20.0.4'
- OCN2: '10.20.0.5'
- installer_master: '10.20.0.2'
- installer_master_username: 'root'
- installer_master_password: 'r00tme'
-multisite:
- fuel_environment:
- installer_username: 'root'
- installer_password: 'r00tme'
- compass_environment:
- installer_username: 'root'
- installer_password: 'root'
- multisite_controller_ip: '10.1.0.50'
-promise:
- tenant_name: promise
- tenant_description: promise Functionality Testing
- user_name: promiser
- user_pwd: test
- image_name: promise-img
- flavor_name: promise-flavor
- flavor_vcpus: 1
- flavor_ram: 128
- flavor_disk: 0
- network_name: promise-net
- subnet_name: promise-subnet
- subnet_cidr: 192.168.121.0/24
- 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
-
-results:
- test_db_url: http://testresults.opnfv.org/test/api/v1
+general:
+ dir:
+ # Relative to the path where the repo is cloned:
+ vping: functest/opnfv_tests/openstack/vping
+ dir_odl: functest/opnfv_tests/sdn/odl
+ 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
+ home: /home/opnfv
+ repos: /home/opnfv/repos
+ repo_functest: /home/opnfv/repos/functest
+ dir_repo_rally: /home/opnfv/repos/rally
+ repo_tempest: /home/opnfv/repos/tempest
+ dir_repo_releng: /home/opnfv/repos/releng
+ dir_repo_vims_test: /home/opnfv/repos/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
+ repo_copper: /home/opnfv/repos/copper
+ dir_repo_ovno: /home/opnfv/repos/ovno
+ 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/
+ rally_inst: /home/opnfv/.rally
+
+ openstack:
+ creds: /home/opnfv/functest/conf/openstack.creds
+ snapshot_file: /home/opnfv/functest/conf/openstack_snapshot.yaml
+
+ image_name: Cirros-0.3.4
+ image_file_name: cirros-0.3.4-x86_64-disk.img
+ image_disk_format: qcow2
+
+ flavor_name: opnfv_flavor
+ flavor_ram: 512
+ flavor_disk: 1
+ flavor_vcpus: 1
+
+ # Private network for functest. Will be created by config_functest.py
+ neutron_private_net_name: functest-net
+ neutron_private_subnet_name: functest-subnet
+ neutron_private_subnet_cidr: 192.168.120.0/24
+ neutron_private_subnet_start: 192.168.120.2
+ neutron_private_subnet_end: 192.168.120.254
+ neutron_private_subnet_gateway: 192.168.120.254
+ neutron_router_name: functest-router
+
+ functest:
+ testcases_yaml: /home/opnfv/repos/functest/functest/ci/testcases.yaml
+
+healthcheck:
+ disk_image: /home/opnfv/functest/data/cirros-0.3.4-x86_64-disk.img
+ disk_format: qcow2
+ wait_time: 60
+
+snaps:
+ use_keystone: True
+ use_floating_ips: False
+
+vping:
+ ping_timeout: 200
+ vm_flavor: m1.tiny # adapt to your environment
+ vm_name_1: opnfv-vping-1
+ vm_name_2: opnfv-vping-2
+ image_name: functest-vping
+ 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
+ image_name: TestSfcVm
+ image_file_name: firewall_block_image.img
+
+tempest:
+ identity:
+ tenant_name: tempest
+ tenant_description: Tenant for Tempest test suite
+ user_name: tempest
+ user_password: tempest
+ validation:
+ ssh_timeout: 130
+ private_net_name: tempest-net
+ private_subnet_name: tempest-subnet
+ private_subnet_cidr: 192.168.150.0/24
+ router_name: tempest-router
+ use_custom_images: False
+ use_custom_flavors: False
+
+rally:
+ deployment_name: opnfv-rally
+ network_name: rally-net
+ subnet_name: rally-subnet
+ 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
+ONOS:
+ general:
+ onosbench_username: 'root'
+ onosbench_password: 'root'
+ onoscli_username: 'root'
+ onoscli_password: 'root'
+ runtimeout: 300
+ environment:
+ OCT: '10.20.0.1'
+ OC1: '10.20.0.7'
+ OC2: '10.20.0.7'
+ OC3: '10.20.0.7'
+ OCN: '10.20.0.4'
+ OCN2: '10.20.0.5'
+ installer_master: '10.20.0.2'
+ installer_master_username: 'root'
+ installer_master_password: 'r00tme'
+multisite:
+ fuel:
+ installer_username: 'root'
+ installer_password: 'r00tme'
+ compass:
+ installer_username: 'root'
+ installer_password: 'root'
+ multisite_controller_ip: '10.1.0.50'
+promise:
+ tenant_name: promise
+ tenant_description: promise Functionality Testing
+ user_name: promiser
+ user_pwd: test
+ image_name: promise-img
+ flavor_name: promise-flavor
+ flavor_vcpus: 1
+ flavor_ram: 128
+ flavor_disk: 0
+ network_name: promise-net
+ subnet_name: promise-subnet
+ subnet_cidr: 192.168.121.0/24
+ router_name: promise-router
+
+example:
+ vm_name: example-vm
+ flavor: m1.small
+ image_name: functest-example-vm
+ private_net_name: example-net
+ private_subnet_name: example-subnet
+ private_subnet_cidr: 192.168.170.0/24
+ router_name: example-router
+ sg_name: example-sg
+ sg_desc: Example Security group
+
+results:
+ test_db_url: http://testresults.opnfv.org/test/api/v1
diff --git a/functest/ci/exec_test.sh b/functest/ci/exec_test.sh
index 913ce08ec..109de078f 100755
--- a/functest/ci/exec_test.sh
+++ b/functest/ci/exec_test.sh
@@ -61,17 +61,7 @@ function odl_tests(){
fi
}
-function sfc_prepare(){
- ids=($(neutron security-group-list|grep default|awk '{print $2}'))
- for id in ${ids[@]}; do
- if ! neutron security-group-show $id|grep "22/tcp" &>/dev/null; then
- neutron security-group-rule-create --protocol tcp \
- --port-range-min 22 --port-range-max 22 --direction ingress $id
- neutron security-group-rule-create --protocol tcp \
- --port-range-min 22 --port-range-max 22 --direction egress $id
- fi
- done
-}
+
function run_test(){
test_name=$1
@@ -93,14 +83,6 @@ function run_test(){
--ospassword ${OS_PASSWORD} \
--odlip $odl_ip --odlwebport $odl_port ${args}
;;
- "tempest_smoke_serial")
- python ${FUNCTEST_TEST_DIR}/openstack/tempest/run_tempest.py \
- $clean_flag -s -m smoke $report
- ;;
- "tempest_full_parallel")
- python ${FUNCTEST_TEST_DIR}/openstack/tempest/run_tempest.py \
- $serial_flag $clean_flag -m full $report
- ;;
"vims")
python ${FUNCTEST_TEST_DIR}/vnf/ims/vims.py $clean_flag $report
;;
@@ -132,7 +114,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
@@ -140,19 +122,6 @@ function run_test(){
"moon")
python ${REPOS_DIR}/moon/tests/run_tests.py $report
;;
- "multisite")
- python ${FUNCTEST_TEST_DIR}/openstack/tempest/gen_tempest_conf.py
- python ${FUNCTEST_TEST_DIR}/openstack/tempest/run_tempest.py \
- $clean_flag -s -m feature_multisite $report \
- -c ${FUNCTEST_TEST_DIR}/openstack/tempest/tempest_multisite.conf
- ;;
- "odl-sfc")
- ODL_SFC_DIR=${REPOS_DIR}/sfc/tests/functest/odl-sfc
- # pass FUNCTEST_REPO_DIR inside prepare_odl_sfc.bash
- FUNCTEST_REPO_DIR=${FUNCTEST_REPO_DIR} python ${ODL_SFC_DIR}/prepare_odl_sfc.py || exit $?
- source ${ODL_SFC_DIR}/tackerc
- python ${ODL_SFC_DIR}/sfc.py $report
- ;;
*)
echo "The test case '${test_name}' does not exist."
exit 1
@@ -197,10 +166,6 @@ done
echo "Sourcing Credentials ${creds} to run the test.."
source ${creds}
-# ODL Boron workaround to create additional flow rules to allow port 22 TCP
-if [[ $DEPLOY_SCENARIO == *"odl_l2-sfc"* ]]; then
- sfc_prepare
-fi
# Run test
run_test $TEST
diff --git a/functest/ci/generate_report.py b/functest/ci/generate_report.py
index a90bc5553..89d8fc628 100755
--- a/functest/ci/generate_report.py
+++ b/functest/ci/generate_report.py
@@ -1,11 +1,17 @@
+#!/usr/bin/env python
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+#
import json
import re
import urllib2
import functest.utils.functest_logger as ft_logger
import functest.utils.functest_utils as ft_utils
-import functest.utils.functest_constants as ft_constants
-
+from functest.utils.constants import CONST
COL_1_LEN = 25
COL_2_LEN = 15
@@ -17,14 +23,6 @@ COL_5_LEN = 75
# and then we can print the url to the specific test result
-class GlobalVariables:
- IS_CI_RUN = ft_constants.IS_CI_RUN
- BUILD_TAG = ft_constants.CI_BUILD_TAG
- INSTALLER = ft_constants.CI_INSTALLER_TYPE
- CI_LOOP = ft_constants.CI_LOOP
- SCENARIO = ft_constants.CI_SCENARIO
-
-
logger = ft_logger.Logger("generate_report").getLogger()
@@ -42,7 +40,7 @@ def init(tiers_to_run):
def get_results_from_db():
url = "%s/results?build_tag=%s" % (ft_utils.get_db_url(),
- GlobalVariables.BUILD_TAG)
+ CONST.BUILD_TAG)
logger.debug("Query to rest api: %s" % url)
try:
data = json.load(urllib2.urlopen(url))
@@ -69,7 +67,7 @@ def print_line(w1, w2='', w3='', w4='', w5=''):
'| ' + w2.ljust(COL_2_LEN - 1) +
'| ' + w3.ljust(COL_3_LEN - 1) +
'| ' + w4.ljust(COL_4_LEN - 1))
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
str += ('| ' + w5.ljust(COL_5_LEN - 1))
str += '|\n'
return str
@@ -77,7 +75,7 @@ def print_line(w1, w2='', w3='', w4='', w5=''):
def print_line_no_columns(str):
TOTAL_LEN = COL_1_LEN + COL_2_LEN + COL_3_LEN + COL_4_LEN + 2
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
TOTAL_LEN += COL_5_LEN + 1
return ('| ' + str.ljust(TOTAL_LEN) + "|\n")
@@ -87,7 +85,7 @@ def print_separator(char="=", delimiter="+"):
delimiter + char * COL_2_LEN +
delimiter + char * COL_3_LEN +
delimiter + char * COL_4_LEN)
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
str += (delimiter + char * COL_5_LEN)
str += '+\n'
return str
@@ -96,7 +94,7 @@ def print_separator(char="=", delimiter="+"):
def main(args):
executed_test_cases = args
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
results = get_results_from_db()
if results is not None:
for test in executed_test_cases:
@@ -105,15 +103,15 @@ def main(args):
"result": data['result']})
TOTAL_LEN = COL_1_LEN + COL_2_LEN + COL_3_LEN + COL_4_LEN
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
TOTAL_LEN += COL_5_LEN
MID = TOTAL_LEN / 2
- if GlobalVariables.BUILD_TAG is not None:
- if re.search("daily", GlobalVariables.BUILD_TAG) is not None:
- GlobalVariables.CI_LOOP = "daily"
+ if CONST.BUILD_TAG is not None:
+ if re.search("daily", CONST.BUILD_TAG) is not None:
+ CONST.CI_LOOP = "daily"
else:
- GlobalVariables.CI_LOOP = "weekly"
+ CONST.CI_LOOP = "weekly"
str = ''
str += print_separator('=', delimiter="=")
@@ -122,19 +120,19 @@ def main(args):
str += print_line_no_columns(' ')
str += print_line_no_columns(" Deployment description:")
str += print_line_no_columns(" INSTALLER: %s"
- % GlobalVariables.INSTALLER)
- if GlobalVariables.SCENARIO is not None:
+ % CONST.INSTALLER_TYPE)
+ if CONST.DEPLOY_SCENARIO is not None:
str += print_line_no_columns(" SCENARIO: %s"
- % GlobalVariables.SCENARIO)
- if GlobalVariables.BUILD_TAG is not None:
+ % CONST.DEPLOY_SCENARIO)
+ if CONST.BUILD_TAG is not None:
str += print_line_no_columns(" BUILD TAG: %s"
- % GlobalVariables.BUILD_TAG)
- if GlobalVariables.CI_LOOP is not None:
+ % CONST.BUILD_TAG)
+ if CONST.CI_LOOP is not None:
str += print_line_no_columns(" CI LOOP: %s"
- % GlobalVariables.CI_LOOP)
+ % CONST.CI_LOOP)
str += print_line_no_columns(' ')
str += print_separator('=')
- if GlobalVariables.IS_CI_RUN:
+ if CONST.IS_CI_RUN:
str += print_line('TEST CASE', 'TIER', 'DURATION', 'RESULT', 'URL')
else:
str += print_line('TEST CASE', 'TIER', 'DURATION', 'RESULT')
diff --git a/functest/ci/prepare_env.py b/functest/ci/prepare_env.py
index 3a99d3bac..3df3a0e0e 100755
--- a/functest/ci/prepare_env.py
+++ b/functest/ci/prepare_env.py
@@ -13,19 +13,20 @@
#
+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 functest.utils.constants import CONST
actions = ['start', 'check']
parser = argparse.ArgumentParser()
@@ -39,7 +40,7 @@ args = parser.parse_args()
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")
@@ -55,95 +56,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.INSTALLERS)
+ "installers are : %s." %
+ (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]
@@ -153,38 +156,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
@@ -199,7 +202,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)
@@ -219,19 +222,19 @@ 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
+ cmd += CONST.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 +
+ CONST.dir_repo_tempest +
" --system-wide")
ft_utils.execute_command(cmd,
error_msg="Problem installing Tempest.")
@@ -254,11 +257,11 @@ def install_rally():
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)
@@ -281,7 +284,7 @@ def main():
verify_deployment()
install_rally()
- 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()
diff --git a/functest/ci/run_tests.py b/functest/ci/run_tests.py
index 3f02c8725..7aac9d2cf 100644..100755
--- a/functest/ci/run_tests.py
+++ b/functest/ci/run_tests.py
@@ -8,24 +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
-
+from functest.utils.constants import CONST
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--test", dest="test", action='store',
@@ -44,7 +43,7 @@ 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
@@ -65,7 +64,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 +74,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():
@@ -124,6 +127,7 @@ def run_test(test, tier_name):
logger.info("Running test case '%s'..." % test_name)
print_separator("=")
logger.debug("\n%s" % test)
+ source_rc_file()
if GlobalVariables.CLEAN_FLAG:
generate_os_snapshot()
@@ -140,9 +144,10 @@ def run_test(test, tier_name):
cls = getattr(module, run_dict['class'])
test_case = cls()
result = test_case.run()
- if (result == testcase_base.TestcaseBase.EX_OK and
- GlobalVariables.REPORT_FLAG):
- test_case.push_to_db()
+ if result == testcase_base.TestcaseBase.EX_OK:
+ if GlobalVariables.REPORT_FLAG:
+ test_case.push_to_db()
+ result = test_case.check_criteria()
except ImportError:
logger.exception("Cannot import module {}".format(
run_dict['module']))
@@ -199,17 +204,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,10 +224,10 @@ def run_all(tiers):
def main():
- 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:
diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml
index f193e1728..6f57c7030 100755
--- a/functest/ci/testcases.yaml
+++ b/functest/ci/testcases.yaml
@@ -67,7 +67,9 @@ tiers:
dependencies:
installer: ''
scenario: ''
-
+ run:
+ module: 'functest.opnfv_tests.openstack.tempest.tempest'
+ class: 'TempestSmokeSerial'
-
name: rally_sanity
criteria: 'success_rate == 100%'
@@ -109,7 +111,7 @@ tiers:
-
name: connection_check
criteria: 'status == "PASS"'
- blocking: true
+ blocking: false
description: >-
This test case verifies the retrieval of OpenStack clients:
Keystone, Glance, Neutron and Nova and may perform some
@@ -127,7 +129,7 @@ tiers:
-
name: api_check
criteria: 'status == "PASS"'
- blocking: true
+ blocking: false
description: >-
This test case verifies the retrieval of OpenStack clients:
Keystone, Glance, Neutron and Nova and may perform some
@@ -145,7 +147,7 @@ tiers:
-
name: snaps_smoke
criteria: 'status == "PASS"'
- blocking: true
+ blocking: false
description: >-
This test case contains tests that setup and destroy
environments with VMs with and without Floating IPs
@@ -222,6 +224,10 @@ tiers:
dependencies:
installer: '(apex)|(joid)'
scenario: '^((?!fdio|lxd).)*$'
+ run:
+ module: 'functest.opnfv_tests.features.copper'
+ class: 'Copper'
+
-
name: moon
criteria: 'status == "PASS"'
@@ -240,6 +246,9 @@ tiers:
dependencies:
installer: '(fuel)|(compass)'
scenario: 'multisite'
+ run:
+ module: 'functest.opnfv_tests.openstack.tempest.tempest'
+ class: 'TempestMultisite'
-
name: odl-sfc
criteria: 'status == "PASS"'
@@ -249,6 +258,9 @@ tiers:
dependencies:
installer: '(apex)|(fuel)'
scenario: 'odl_l2-sfc'
+ run:
+ module: 'functest.opnfv_tests.features.odl_sfc'
+ class: 'OpenDaylightSFC'
-
name: onos_sfc
criteria: 'status == "PASS"'
@@ -288,6 +300,9 @@ tiers:
dependencies:
installer: ''
scenario: ''
+ run:
+ module: 'functest.opnfv_tests.openstack.tempest.tempest'
+ class: 'TempestFullParallel'
-
name: rally_full
diff --git a/functest/cli/cli_base.py b/functest/cli/cli_base.py
index 3b14fa336..cc697ed7e 100644
--- a/functest/cli/cli_base.py
+++ b/functest/cli/cli_base.py
@@ -121,8 +121,11 @@ def testcase_show(testname):
@click.option('-n', '--noclean', is_flag=True, default=False,
help='The created openstack resources by the test'
'will not be cleaned after the execution.')
-def testcase_run(testname, noclean):
- _testcase.run(testname, noclean)
+@click.option('-r', '--report', is_flag=True, default=False,
+ help='Push results to the results DataBase. Only CI Pods'
+ 'have rights to do that.')
+def testcase_run(testname, noclean, report):
+ _testcase.run(testname, noclean, report)
@tier.command('list', help="Lists the available tiers.")
@@ -147,5 +150,8 @@ def tier_gettests(tiername):
@click.option('-n', '--noclean', is_flag=True, default=False,
help='The created openstack resources by the tests'
'will not be cleaned after the execution.')
-def tier_run(tiername, noclean):
- _tier.run(tiername, noclean)
+@click.option('-r', '--report', is_flag=True, default=False,
+ help='Push results to the results DataBase. Only CI Pods'
+ 'have rights to do that.')
+def tier_run(tiername, noclean, report):
+ _tier.run(tiername, noclean, report)
diff --git a/functest/cli/commands/cli_env.py b/functest/cli/commands/cli_env.py
index 9f793e71f..9423631bf 100644
--- a/functest/cli/commands/cli_env.py
+++ b/functest/cli/commands/cli_env.py
@@ -12,8 +12,8 @@ import os
import click
import git
+from functest.utils.constants import CONST
import functest.utils.functest_utils as ft_utils
-import functest.utils.functest_constants as ft_constants
class CliEnv:
@@ -28,7 +28,7 @@ class CliEnv:
"it again? [y|n]\n")
while True:
if answer.lower() in ["y", "yes"]:
- os.remove(ft_constants.ENV_FILE)
+ os.remove(CONST.env_active)
break
elif answer.lower() in ["n", "no"]:
return
@@ -36,40 +36,32 @@ class CliEnv:
answer = raw_input("Invalid answer. Please type [y|n]\n")
cmd = ("python %s/functest/ci/prepare_env.py start" %
- ft_constants.FUNCTEST_REPO_DIR)
+ CONST.dir_repo_functest)
ft_utils.execute_command(cmd)
def show(self):
- CI_INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
- if CI_INSTALLER_TYPE is None:
- CI_INSTALLER_TYPE = "Unknown"
- CI_INSTALLER_IP = ft_constants.CI_INSTALLER_IP
- if CI_INSTALLER_IP is None:
- CI_INSTALLER_IP = "Unknown"
- CI_INSTALLER = ("%s, %s" % (CI_INSTALLER_TYPE, CI_INSTALLER_IP))
-
- CI_SCENARIO = ft_constants.CI_SCENARIO
- if CI_SCENARIO is None:
- CI_SCENARIO = "Unknown"
-
- CI_NODE = ft_constants.CI_NODE
- if CI_NODE is None:
- CI_NODE = "Unknown"
-
- repo = git.Repo(ft_constants.FUNCTEST_REPO_DIR)
- branch = repo.head.reference
- GIT_BRANCH = branch.name
- GIT_HASH = branch.commit.hexsha
-
- CI_BUILD_TAG = ft_constants.CI_BUILD_TAG
- if CI_BUILD_TAG is not None:
- CI_BUILD_TAG = CI_BUILD_TAG.lstrip(
+ def _get_value(attr, default='Unknown'):
+ return attr if attr else default
+
+ install_type = _get_value(CONST.INSTALLER_TYPE)
+ installer_ip = _get_value(CONST.INSTALLER_IP)
+ installer_info = ("%s, %s" % (install_type, installer_ip))
+ scenario = _get_value(CONST.DEPLOY_SCENARIO)
+ node = _get_value(CONST.NODE_NAME)
+ repo_h = git.Repo(CONST.dir_repo_functest).head
+ if repo_h.is_detached:
+ git_branch = 'detached from FETCH_HEAD'
+ git_hash = repo_h.commit.hexsha
+ else:
+ branch = repo_h.reference
+ git_branch = branch.name
+ git_hash = branch.commit.hexsha
+ is_debug = _get_value(CONST.CI_DEBUG, 'false')
+ build_tag = CONST.BUILD_TAG
+ if build_tag is not None:
+ build_tag = build_tag.lstrip(
"jenkins-").lstrip("functest").lstrip("-")
- CI_DEBUG = ft_constants.CI_DEBUG
- if CI_DEBUG is None:
- CI_DEBUG = "false"
-
STATUS = "not ready"
if self.status(verbose=False) == 0:
STATUS = "ready"
@@ -77,14 +69,14 @@ class CliEnv:
click.echo("+======================================================+")
click.echo("| Functest Environment info |")
click.echo("+======================================================+")
- click.echo("| INSTALLER: %s|" % CI_INSTALLER.ljust(41))
- click.echo("| SCENARIO: %s|" % CI_SCENARIO.ljust(41))
- click.echo("| POD: %s|" % CI_NODE.ljust(41))
- click.echo("| GIT BRACNH: %s|" % GIT_BRANCH.ljust(41))
- click.echo("| GIT HASH: %s|" % GIT_HASH.ljust(41))
- if CI_BUILD_TAG:
- click.echo("| BUILD TAG: %s|" % CI_BUILD_TAG.ljust(41))
- click.echo("| DEBUG FLAG: %s|" % CI_DEBUG.ljust(41))
+ click.echo("| INSTALLER: %s|" % installer_info.ljust(41))
+ click.echo("| SCENARIO: %s|" % scenario.ljust(41))
+ click.echo("| POD: %s|" % node.ljust(41))
+ click.echo("| GIT BRACNH: %s|" % git_branch.ljust(41))
+ click.echo("| GIT HASH: %s|" % git_hash.ljust(41))
+ if build_tag:
+ click.echo("| BUILD TAG: %s|" % build_tag.ljust(41))
+ click.echo("| DEBUG FLAG: %s|" % is_debug.ljust(41))
click.echo("+------------------------------------------------------+")
click.echo("| STATUS: %s|" % STATUS.ljust(41))
click.echo("+------------------------------------------------------+")
@@ -92,7 +84,7 @@ class CliEnv:
def status(self, verbose=True):
ret_val = 0
- if not os.path.isfile(ft_constants.ENV_FILE):
+ if not os.path.isfile(CONST.env_active):
if verbose:
click.echo("Functest environment is not installed.\n")
ret_val = 1
diff --git a/functest/cli/commands/cli_os.py b/functest/cli/commands/cli_os.py
index bb8592195..aeb34974f 100644
--- a/functest/cli/commands/cli_os.py
+++ b/functest/cli/commands/cli_os.py
@@ -12,23 +12,21 @@ import os
import click
+from functest.utils.constants import CONST
import functest.utils.functest_utils as ft_utils
import functest.utils.openstack_clean as os_clean
import functest.utils.openstack_snapshot as os_snapshot
-import functest.utils.functest_constants as ft_constants
-
-
-OPENSTACK_RC_FILE = ft_constants.OPENSTACK_CREDS
-OPENSTACK_SNAPSHOT_FILE = ft_constants.OPENSTACK_SNAPSHOT_FILE
class CliOpenStack:
def __init__(self):
- self.os_auth_url = ft_constants.OS_AUTH_URL
+ self.os_auth_url = CONST.OS_AUTH_URL
self.endpoint_ip = None
self.endpoint_port = None
- if self.os_auth_url is not None:
+ self.openstack_creds = CONST.openstack_creds
+ self.snapshot_file = CONST.openstack_snapshot_file
+ if self.os_auth_url:
self.endpoint_ip = self.os_auth_url.rsplit("/")[2].rsplit(":")[0]
self.endpoint_port = self.os_auth_url.rsplit("/")[2].rsplit(":")[1]
@@ -43,13 +41,14 @@ class CliOpenStack:
click.echo("Cannot talk to the endpoint %s\n" % self.endpoint_ip)
exit(0)
- def show_credentials(self):
+ @staticmethod
+ def show_credentials():
for key, value in os.environ.items():
if key.startswith('OS_'):
click.echo("{}={}".format(key, value))
def fetch_credentials(self):
- if os.path.isfile(OPENSTACK_RC_FILE):
+ if os.path.isfile(self.openstack_creds):
answer = raw_input("It seems the RC file is already present. "
"Do you want to overwrite it? [y|n]\n")
while True:
@@ -60,31 +59,31 @@ class CliOpenStack:
else:
answer = raw_input("Invalid answer. Please type [y|n]\n")
- CI_INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
- if CI_INSTALLER_TYPE is None:
+ installer_type = CONST.INSTALLER_TYPE
+ if installer_type is None:
click.echo("The environment variable 'INSTALLER_TYPE' is not"
"defined. Please export it")
- CI_INSTALLER_IP = ft_constants.CI_INSTALLER_IP
- if CI_INSTALLER_IP is None:
+ installer_ip = CONST.INSTALLER_IP
+ if installer_ip is None:
click.echo("The environment variable 'INSTALLER_IP' is not"
"defined. Please export it")
cmd = ("%s/releng/utils/fetch_os_creds.sh -d %s -i %s -a %s"
- % (ft_constants.REPOS_DIR,
- OPENSTACK_RC_FILE,
- CI_INSTALLER_TYPE,
- CI_INSTALLER_IP))
+ % (CONST.dir_repos,
+ self.openstack_creds,
+ installer_type,
+ installer_ip))
click.echo("Fetching credentials from installer node '%s' with IP=%s.."
- % (CI_INSTALLER_TYPE, CI_INSTALLER_IP))
+ % (installer_type, installer_ip))
ft_utils.execute_command(cmd, verbose=False)
def check(self):
self.ping_endpoint()
- cmd = ft_constants.FUNCTEST_REPO_DIR + "/functest/ci/check_os.sh"
+ cmd = CONST.dir_repo_functest + "/functest/ci/check_os.sh"
ft_utils.execute_command(cmd, verbose=False)
def snapshot_create(self):
self.ping_endpoint()
- if os.path.isfile(OPENSTACK_SNAPSHOT_FILE):
+ if os.path.isfile(self.snapshot_file):
answer = raw_input("It seems there is already an OpenStack "
"snapshot. Do you want to overwrite it with "
"the current OpenStack status? [y|n]\n")
@@ -100,18 +99,18 @@ class CliOpenStack:
os_snapshot.main()
def snapshot_show(self):
- if not os.path.isfile(OPENSTACK_SNAPSHOT_FILE):
+ if not os.path.isfile(self.snapshot_file):
click.echo("There is no OpenStack snapshot created. To create "
"one run the command "
"'functest openstack snapshot-create'")
return
- with open(OPENSTACK_SNAPSHOT_FILE, 'r') as yaml_file:
+ with open(self.snapshot_file, 'r') as yaml_file:
click.echo("\n%s"
% yaml_file.read())
def clean(self):
self.ping_endpoint()
- if not os.path.isfile(OPENSTACK_SNAPSHOT_FILE):
+ if not os.path.isfile(self.snapshot_file):
click.echo("Not possible to clean OpenStack without a snapshot. "
"This could cause problems. "
"Run first the command "
diff --git a/functest/cli/commands/cli_testcase.py b/functest/cli/commands/cli_testcase.py
index efe177d52..b6566245a 100644
--- a/functest/cli/commands/cli_testcase.py
+++ b/functest/cli/commands/cli_testcase.py
@@ -14,19 +14,17 @@ import os
import click
import functest.ci.tier_builder as tb
+from functest.utils.constants import CONST
import functest.utils.functest_utils as ft_utils
import functest.utils.functest_vacation as vacation
-import functest.utils.functest_constants as ft_constants
class CliTestcase:
def __init__(self):
- CI_INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
- CI_SCENARIO = ft_constants.CI_SCENARIO
- testcases = ft_constants.FUNCTEST_TESTCASES_YAML
-
- self.tiers = tb.TierBuilder(CI_INSTALLER_TYPE, CI_SCENARIO, testcases)
+ self.tiers = tb.TierBuilder(CONST.INSTALLER_TYPE,
+ CONST.DEPLOY_SCENARIO,
+ CONST.functest_testcases_yaml)
def list(self):
summary = ""
@@ -43,17 +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:
- if noclean:
- cmd = ("python %s/functest/ci/run_tests.py "
- "-n -t %s" % (ft_constants.FUNCTEST_REPO_DIR, testname))
- else:
+ tests = testname.split(",")
+ for test in tests:
cmd = ("python %s/functest/ci/run_tests.py "
- "-t %s" % (ft_constants.FUNCTEST_REPO_DIR, testname))
- ft_utils.execute_command(cmd)
+ "%s -t %s" % (CONST.dir_repo_functest, flags, test))
+ ft_utils.execute_command(cmd)
diff --git a/functest/cli/commands/cli_tier.py b/functest/cli/commands/cli_tier.py
index 9da51072a..b9d25b6d0 100644
--- a/functest/cli/commands/cli_tier.py
+++ b/functest/cli/commands/cli_tier.py
@@ -14,17 +14,16 @@ import os
import click
import functest.ci.tier_builder as tb
+from functest.utils.constants import CONST
import functest.utils.functest_utils as ft_utils
-import functest.utils.functest_constants as ft_constants
class CliTier:
def __init__(self):
- CI_INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
- CI_SCENARIO = ft_constants.CI_SCENARIO
- testcases = ft_constants.FUNCTEST_TESTCASES_YAML
- self.tiers = tb.TierBuilder(CI_INSTALLER_TYPE, CI_SCENARIO, testcases)
+ self.tiers = tb.TierBuilder(CONST.INSTALLER_TYPE,
+ CONST.DEPLOY_SCENARIO,
+ CONST.functest_testcases_yaml)
def list(self):
summary = ""
@@ -54,15 +53,19 @@ class CliTier:
tests = tier.get_test_names()
click.echo("Test cases in tier '%s':\n %s\n" % (tiername, tests))
- def run(self, tiername, noclean=False):
- if not os.path.isfile(ft_constants.ENV_FILE):
+ @staticmethod
+ def run(tiername, noclean=False, report=False):
+
+ flags = ""
+ if noclean:
+ flags += "-n "
+ if report:
+ flags += "-r "
+
+ if not os.path.isfile(CONST.env_active):
click.echo("Functest environment is not ready. "
"Run first 'functest env prepare'")
else:
- if noclean:
- cmd = ("python %s/functest/ci/run_tests.py "
- "-n -t %s" % (ft_constants.FUNCTEST_REPO_DIR, tiername))
- else:
- cmd = ("python %s/functest/ci/run_tests.py "
- "-t %s" % (ft_constants.FUNCTEST_REPO_DIR, tiername))
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, flags, tiername))
ft_utils.execute_command(cmd)
diff --git a/functest/core/feature_base.py b/functest/core/feature_base.py
index 01a27f305..873e21dae 100644
--- a/functest/core/feature_base.py
+++ b/functest/core/feature_base.py
@@ -3,6 +3,7 @@ import time
import testcase_base as base
import functest.utils.functest_utils as ft_utils
import functest.utils.functest_logger as ft_logger
+from functest.utils.constants import CONST
class FeatureBase(base.TestcaseBase):
@@ -11,7 +12,7 @@ class FeatureBase(base.TestcaseBase):
self.project_name = project
self.case_name = case
self.cmd = cmd
- self.repo = self.get_conf('general.directories.{}'.format(repo))
+ self.repo = CONST.__getattribute__(repo)
self.result_file = self.get_result_file()
self.logger = ft_logger.Logger(project).getLogger()
@@ -44,15 +45,10 @@ class FeatureBase(base.TestcaseBase):
return exit_code
def get_result_file(self):
- dir = self.get_conf('general.directories.dir_results')
- return "{}/{}.log".format(dir, self.project_name)
+ return "{}/{}.log".format(CONST.dir_results, self.project_name)
def log_results(self):
ft_utils.logger_test_results(self.project_name,
self.case_name,
self.criteria,
self.details)
-
- @staticmethod
- def get_conf(parameter):
- return ft_utils.get_functest_config(parameter)
diff --git a/functest/core/pytest_suite_runner.py b/functest/core/pytest_suite_runner.py
index 2d5b2667b..1eed92b57 100644..100755
--- a/functest/core/pytest_suite_runner.py
+++ b/functest/core/pytest_suite_runner.py
@@ -41,8 +41,8 @@ class PyTestSuiteRunner(base.TestcaseBase):
for test, message in result.failures:
self.logger.error(str(test) + " FAILED with " + message)
- if (result.errors and len(result.errors) > 0) \
- or (result.failures and len(result.failures) > 0):
+ if ((result.errors and len(result.errors) > 0)
+ or (result.failures and len(result.failures) > 0)):
self.logger.info("%s FAILED" % self.case_name)
self.criteria = 'FAIL'
exit_code = base.TestcaseBase.EX_RUN_ERROR
diff --git a/functest/core/testcase_base.py b/functest/core/testcase_base.py
index e869803d8..838b63983 100644
--- a/functest/core/testcase_base.py
+++ b/functest/core/testcase_base.py
@@ -18,6 +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_TESTCASE_FAILED = os.EX_SOFTWARE - 2
logger = ft_logger.Logger(__name__).getLogger()
@@ -29,6 +30,15 @@ class TestcaseBase(object):
self.start_time = ""
self.stop_time = ""
+ def check_criteria(self):
+ try:
+ assert self.criteria
+ if self.criteria == 'PASS':
+ return TestcaseBase.EX_OK
+ except:
+ self.logger.error("Please run test before checking the results")
+ return TestcaseBase.EX_TESTCASE_FAILED
+
def run(self, **kwargs):
self.logger.error("Run must be implemented")
return TestcaseBase.EX_RUN_ERROR
diff --git a/functest/opnfv_tests/features/copper.py b/functest/opnfv_tests/features/copper.py
index d003779e8..8d5393c95 100755
--- a/functest/opnfv_tests/features/copper.py
+++ b/functest/opnfv_tests/features/copper.py
@@ -14,70 +14,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-import argparse
-import sys
-import time
+import functest.core.feature_base as base
-import functest.utils.functest_logger as ft_logger
-import functest.utils.functest_utils as functest_utils
-import functest.utils.functest_constants as ft_constants
-parser = argparse.ArgumentParser()
-parser.add_argument("-r", "--report",
- help="Create json result file",
- action="store_true")
-args = parser.parse_args()
-
-COPPER_REPO_DIR = ft_constants.COPPER_REPO_DIR
-RESULTS_DIR = ft_constants.FUNCTEST_RESULTS_DIR
-
-logger = ft_logger.Logger("copper").getLogger()
-
-
-def main():
- cmd = "%s/tests/run.sh %s/tests" % (COPPER_REPO_DIR, COPPER_REPO_DIR)
-
- start_time = time.time()
-
- log_file = RESULTS_DIR + "/copper.log"
- ret_val = functest_utils.execute_command(cmd,
- output_file=log_file)
-
- stop_time = time.time()
- duration = round(stop_time - start_time, 1)
- if ret_val == 0:
- logger.info("COPPER PASSED")
- test_status = 'PASS'
- else:
- logger.info("COPPER FAILED")
- test_status = 'FAIL'
-
- details = {
- 'timestart': start_time,
- 'duration': duration,
- 'status': test_status,
- }
- functest_utils.logger_test_results("Copper",
- "copper-notification",
- details['status'], details)
- try:
- if args.report:
- functest_utils.push_results_to_db("copper",
- "copper-notification",
- start_time,
- stop_time,
- details['status'],
- details)
- logger.info("COPPER results pushed to DB")
- except:
- logger.error("Error pushing results into Database '%s'"
- % sys.exc_info()[0])
-
- if ret_val != 0:
- sys.exit(-1)
-
- sys.exit(0)
-
-
-if __name__ == '__main__':
- main()
+class Copper(base.FeatureBase):
+ def __init__(self):
+ 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)
diff --git a/functest/opnfv_tests/features/odl_sfc.py b/functest/opnfv_tests/features/odl_sfc.py
new file mode 100644
index 000000000..3b68d4204
--- /dev/null
+++ b/functest/opnfv_tests/features/odl_sfc.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2016 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 functest.core.feature_base as base
+
+
+class OpenDaylightSFC(base.FeatureBase):
+
+ def __init__(self):
+ super(OpenDaylightSFC, self).__init__(project='sfc',
+ case='functest-odl-sfc"',
+ repo='dir_repo_sfc')
+ dir_sfc_functest = '{}/sfc/tests/functest'.format(self.repo)
+ self.cmd = 'cd %s && python ./run_tests.py' % dir_sfc_functest
diff --git a/functest/opnfv_tests/features/sdnvpn.py b/functest/opnfv_tests/features/sdnvpn.py
index 451299eb3..1919a03c2 100644..100755
--- a/functest/opnfv_tests/features/sdnvpn.py
+++ b/functest/opnfv_tests/features/sdnvpn.py
@@ -7,70 +7,14 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
#
+import functest.core.feature_base as base
-import argparse
-import os
-import sys
-import time
-
-import functest.core.testcase_base as testcase_base
-import functest.utils.functest_constants as ft_constants
-import functest.utils.functest_logger as ft_logger
-import functest.utils.functest_utils as ft_utils
-
-
-class SdnVpnTests(testcase_base.TestcaseBase):
- SDNVPN_REPO_TESTS = os.path.join(
- ft_constants.SDNVPN_REPO_DIR, "tests/functest")
- logger = ft_logger.Logger("sdnvpn").getLogger()
+class SdnVpnTests(base.FeatureBase):
def __init__(self):
- super(SdnVpnTests, self).__init__()
- self.project_name = "sdnvpn"
- self.case_name = "bgpvpn"
-
- def main(self, **kwargs):
- os.chdir(self.SDNVPN_REPO_TESTS)
- cmd = 'run_tests.py'
- log_file = os.path.join(
- ft_constants.FUNCTEST_RESULTS_DIR, "sdnvpn.log")
- start_time = time.time()
-
- ret = ft_utils.execute_command(cmd,
- output_file=log_file)
-
- stop_time = time.time()
- if ret == 0:
- self.logger.info("%s OK" % self.case_name)
- status = 'PASS'
- else:
- self.logger.info("%s FAILED" % self.case_name)
- status = "FAIL"
-
- # report status only if tests run (FAIL OR PASS)
- self.criteria = status
- self.start_time = start_time
- self.stop_time = stop_time
- self.details = {}
-
- def run(self):
- kwargs = {}
- return self.main(**kwargs)
-
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser()
- parser.add_argument("-r", "--report",
- help="Create json result file",
- action="store_true")
- args = vars(parser.parse_args())
- sdnvpn = SdnVpnTests()
- try:
- result = sdnvpn.main(**args)
- if result != testcase_base.TestcaseBase.EX_OK:
- sys.exit(result)
- if args['report']:
- sys.exit(sdnvpn.push_to_db())
- except Exception:
- sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)
+ super(SdnVpnTests, self).__init__(project='sdnvpn',
+ case='bgpvpn',
+ repo='dir_repo_sdnvpn')
+ dir_sfc_functest = '{}/sdnvpn/test/functest'.format(self.repo)
+ self.cmd = 'cd %s && python ./run_tests.py' % dir_sfc_functest
diff --git a/functest/opnfv_tests/openstack/examples/create_instance_and_ip.py b/functest/opnfv_tests/openstack/examples/create_instance_and_ip.py
index b4e2e519b..b44008642 100755
--- a/functest/opnfv_tests/openstack/examples/create_instance_and_ip.py
+++ b/functest/opnfv_tests/openstack/examples/create_instance_and_ip.py
@@ -14,9 +14,9 @@ import argparse
import os
import sys
+from functest.utils.constants import CONST
import functest.utils.functest_logger as ft_logger
import functest.utils.openstack_utils as os_utils
-import functest.utils.functest_constants as ft_constants
parser = argparse.ArgumentParser()
@@ -29,26 +29,26 @@ args = parser.parse_args()
""" logging configuration """
logger = ft_logger.Logger("create_instance_and_ip").getLogger()
-HOME = ft_constants.HOME + "/"
+HOME = CONST.dir_home + "/"
VM_BOOT_TIMEOUT = 180
-EXAMPLE_INSTANCE_NAME = ft_constants.EXAMPLE_INSTANCE_NAME
-EXAMPLE_FLAVOR = ft_constants.EXAMPLE_FLAVOR
-EXAMPLE_IMAGE_NAME = ft_constants.EXAMPLE_IMAGE_NAME
-IMAGE_FILENAME = ft_constants.GLANCE_IMAGE_FILENAME
-IMAGE_FORMAT = ft_constants.GLANCE_IMAGE_FORMAT
-IMAGE_PATH = os.path.join(ft_constants.FUNCTEST_DATA_DIR, IMAGE_FILENAME)
+EXAMPLE_INSTANCE_NAME = CONST.example_vm_name
+EXAMPLE_FLAVOR = CONST.example_flavor
+EXAMPLE_IMAGE_NAME = CONST.example_image_name
+IMAGE_FILENAME = CONST.openstack_image_file_name
+IMAGE_FORMAT = CONST.openstack_image_disk_format
+IMAGE_PATH = os.path.join(CONST.dir_functest_data, IMAGE_FILENAME)
# NEUTRON Private Network parameters
-EXAMPLE_PRIVATE_NET_NAME = ft_constants.EXAMPLE_PRIVATE_NET_NAME
-EXAMPLE_PRIVATE_SUBNET_NAME = ft_constants.EXAMPLE_PRIVATE_SUBNET_NAME
-EXAMPLE_PRIVATE_SUBNET_CIDR = ft_constants.EXAMPLE_PRIVATE_SUBNET_CIDR
-EXAMPLE_ROUTER_NAME = ft_constants.EXAMPLE_ROUTER_NAME
+EXAMPLE_PRIVATE_NET_NAME = CONST.example_private_net_name
+EXAMPLE_PRIVATE_SUBNET_NAME = CONST.example_private_subnet_name
+EXAMPLE_PRIVATE_SUBNET_CIDR = CONST.example_private_subnet_cidr
+EXAMPLE_ROUTER_NAME = CONST.example_router_name
-EXAMPLE_SECGROUP_NAME = ft_constants.EXAMPLE_SECGROUP_NAME
-EXAMPLE_SECGROUP_DESCR = ft_constants.EXAMPLE_SECGROUP_DESCR
+EXAMPLE_SECGROUP_NAME = CONST.example_sg_name
+EXAMPLE_SECGROUP_DESCR = CONST.example_sg_desc
def main():
@@ -64,11 +64,12 @@ def main():
container="bare",
public=True)
- network_dic = os_utils.create_network_full(neutron_client,
- EXAMPLE_PRIVATE_NET_NAME,
- EXAMPLE_PRIVATE_SUBNET_NAME,
- EXAMPLE_ROUTER_NAME,
- EXAMPLE_PRIVATE_SUBNET_CIDR)
+ network_dic = os_utils.create_network_full(
+ neutron_client,
+ EXAMPLE_PRIVATE_NET_NAME,
+ EXAMPLE_PRIVATE_SUBNET_NAME,
+ EXAMPLE_ROUTER_NAME,
+ EXAMPLE_PRIVATE_SUBNET_CIDR)
if not network_dic:
logger.error(
"There has been a problem when creating the neutron network")
@@ -86,11 +87,11 @@ def main():
"Configuration:\n name=%s \n flavor=%s \n image=%s \n "
"network=%s \n"
% (EXAMPLE_INSTANCE_NAME, EXAMPLE_FLAVOR, image_id, network_id))
- instance = \
- os_utils.create_instance_and_wait_for_active(EXAMPLE_FLAVOR,
- image_id,
- network_id,
- EXAMPLE_INSTANCE_NAME)
+ instance = os_utils.create_instance_and_wait_for_active(
+ EXAMPLE_FLAVOR,
+ image_id,
+ network_id,
+ EXAMPLE_INSTANCE_NAME)
if instance is None:
logger.error("Error while booting instance.")
diff --git a/functest/opnfv_tests/openstack/rally/run_rally-cert.py b/functest/opnfv_tests/openstack/rally/run_rally-cert.py
index 6d8f01602..ec22b52d8 100755
--- a/functest/opnfv_tests/openstack/rally/run_rally-cert.py
+++ b/functest/opnfv_tests/openstack/rally/run_rally-cert.py
@@ -15,20 +15,20 @@
#
""" 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 +71,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 +86,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 +180,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 +270,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']:
diff --git a/functest/opnfv_tests/openstack/snaps/api_check.py b/functest/opnfv_tests/openstack/snaps/api_check.py
index e6ee81e9d..17d05b922 100644
--- a/functest/opnfv_tests/openstack/snaps/api_check.py
+++ b/functest/opnfv_tests/openstack/snaps/api_check.py
@@ -5,11 +5,13 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
-import functest.utils.functest_utils as ft_utils
+import unittest
+
+from snaps import test_suite_builder
+
from functest.core.pytest_suite_runner import PyTestSuiteRunner
from functest.opnfv_tests.openstack.snaps import snaps_utils
-from snaps import test_suite_builder
-import unittest
+from functest.utils.constants import CONST
class ApiCheck(PyTestSuiteRunner):
@@ -22,10 +24,11 @@ class ApiCheck(PyTestSuiteRunner):
super(ApiCheck, self).__init__()
self.suite = unittest.TestSuite()
- creds_file = ft_utils.get_functest_config('general.openstack.creds')
- use_key = ft_utils.get_functest_config('snaps.use_keystone')
+ self.case_name = "api_check"
ext_net_name = snaps_utils.get_ext_net_name()
- test_suite_builder.add_openstack_api_tests(self.suite, creds_file,
- ext_net_name,
- use_keystone=use_key)
+ test_suite_builder.add_openstack_api_tests(
+ self.suite,
+ CONST.openstack_creds,
+ ext_net_name,
+ use_keystone=CONST.snaps_use_keystone)
diff --git a/functest/opnfv_tests/openstack/snaps/connection_check.py b/functest/opnfv_tests/openstack/snaps/connection_check.py
index 42e38d67c..11f8ad074 100644
--- a/functest/opnfv_tests/openstack/snaps/connection_check.py
+++ b/functest/opnfv_tests/openstack/snaps/connection_check.py
@@ -5,11 +5,13 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
-import functest.utils.functest_utils as ft_utils
+import unittest
+
+from snaps import test_suite_builder
+
from functest.core.pytest_suite_runner import PyTestSuiteRunner
from functest.opnfv_tests.openstack.snaps import snaps_utils
-from snaps import test_suite_builder
-import unittest
+from functest.utils.constants import CONST
class ConnectionCheck(PyTestSuiteRunner):
@@ -22,10 +24,11 @@ class ConnectionCheck(PyTestSuiteRunner):
super(ConnectionCheck, self).__init__()
self.suite = unittest.TestSuite()
- creds_file = ft_utils.get_functest_config('general.openstack.creds')
- use_key = ft_utils.get_functest_config('snaps.use_keystone')
+ self.case_name = "connection_check"
ext_net_name = snaps_utils.get_ext_net_name()
- test_suite_builder.add_openstack_client_tests(self.suite, creds_file,
- ext_net_name,
- use_keystone=use_key)
+ test_suite_builder.add_openstack_client_tests(
+ self.suite,
+ CONST.openstack_creds,
+ ext_net_name,
+ use_keystone=CONST.snaps_use_keystone)
diff --git a/functest/opnfv_tests/openstack/snaps/smoke.py b/functest/opnfv_tests/openstack/snaps/smoke.py
index 25433a325..83eb6600c 100644
--- a/functest/opnfv_tests/openstack/snaps/smoke.py
+++ b/functest/opnfv_tests/openstack/snaps/smoke.py
@@ -5,12 +5,14 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
-import functest.utils.functest_utils as ft_utils
+import os
+import unittest
+
+from snaps import test_suite_builder
+
from functest.core.pytest_suite_runner import PyTestSuiteRunner
from functest.opnfv_tests.openstack.snaps import snaps_utils
-from snaps import test_suite_builder
-import unittest
-import os
+from functest.utils.constants import CONST
class SnapsSmoke(PyTestSuiteRunner):
@@ -23,18 +25,19 @@ class SnapsSmoke(PyTestSuiteRunner):
super(SnapsSmoke, self).__init__()
self.suite = unittest.TestSuite()
- 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')
+ self.case_name = "snaps_smoke"
+ use_fip = CONST.snaps_use_floating_ips
ext_net_name = snaps_utils.get_ext_net_name()
# Tests requiring floating IPs leverage files contained within the
# SNAPS repository and are found relative to that path
if use_fip:
- snaps_dir = ft_utils.get_functest_config(
- 'general.directories.dir_repo_snaps') + '/snaps'
+ snaps_dir = CONST.dir_repo_snaps + '/snaps'
os.chdir(snaps_dir)
test_suite_builder.add_openstack_integration_tests(
- self.suite, creds_file, ext_net_name, use_keystone=use_key,
+ self.suite,
+ CONST.openstack_creds,
+ ext_net_name,
+ use_keystone=CONST.snaps_use_keystone,
use_floating_ips=use_fip)
diff --git a/functest/opnfv_tests/openstack/snaps/snaps_utils.py b/functest/opnfv_tests/openstack/snaps/snaps_utils.py
index a25ad3e0d..4ea1a04ad 100644
--- a/functest/opnfv_tests/openstack/snaps/snaps_utils.py
+++ b/functest/opnfv_tests/openstack/snaps/snaps_utils.py
@@ -5,17 +5,18 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
-import functest.utils.functest_utils as ft_utils
from snaps.openstack.tests import openstack_tests
from snaps.openstack.utils import neutron_utils
+from functest.utils.constants import CONST
+
def get_ext_net_name():
"""
Returns the first external network name
:return:
"""
- os_env_file = ft_utils.get_functest_config('general.openstack.creds')
+ os_env_file = CONST.openstack_creds
os_creds = openstack_tests.get_credentials(os_env_file=os_env_file)
neutron = neutron_utils.neutron_client(os_creds)
ext_nets = neutron_utils.get_external_networks(neutron)
diff --git a/functest/opnfv_tests/openstack/tempest/__init__.py b/functest/opnfv_tests/openstack/tempest/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/opnfv_tests/openstack/tempest/__init__.py
diff --git a/functest/opnfv_tests/openstack/tempest/conf_utils.py b/functest/opnfv_tests/openstack/tempest/conf_utils.py
new file mode 100644
index 000000000..5295ff373
--- /dev/null
+++ b/functest/opnfv_tests/openstack/tempest/conf_utils.py
@@ -0,0 +1,190 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2015 All rights reserved
+# This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+import ConfigParser
+import os
+import re
+import shutil
+
+import opnfv.utils.constants as releng_constants
+
+import functest.utils.functest_utils as ft_utils
+from functest.utils.constants import CONST
+
+IMAGE_ID_ALT = None
+FLAVOR_ID_ALT = None
+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')
+TEMPEST_BLACKLIST = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR,
+ 'blacklist.txt')
+TEMPEST_DEFCORE = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR,
+ 'defcore_req.txt')
+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 = 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"
+ 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"
+ ft_utils.execute_command(cmd)
+
+ logger.debug("Finding tempest.conf file...")
+ if not os.path.isfile(tempest_conf_file):
+ logger.error("Tempest configuration file %s NOT found."
+ % tempest_conf_file)
+ return releng_constants.EXIT_RUN_ERROR
+
+ logger.debug("Updating selected tempest.conf parameters...")
+ config = ConfigParser.RawConfigParser()
+ config.read(tempest_conf_file)
+ config.set(
+ 'compute',
+ 'fixed_network_name',
+ 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 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', 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', CONST.tempest_validation_ssh_timeout)
+
+ if CONST.OS_ENDPOINT_TYPE is not None:
+ services_list = ['compute',
+ 'volume',
+ 'image',
+ 'network',
+ 'data-processing',
+ 'object-storage',
+ 'orchestration']
+ sections = config.sections()
+ for service in services_list:
+ if service not in sections:
+ config.add_section(service)
+ config.set(service, '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')
+
+ return releng_constants.EXIT_OK
+
+
+def configure_tempest_multisite(logger, deployment_dir):
+ """
+ Add/update needed parameters into tempest.conf file generated by Rally
+ """
+ logger.debug("configure the tempest")
+ configure_tempest(logger, deployment_dir)
+
+ logger.debug("Finding tempest.conf file...")
+ 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)
+ return releng_constants.EXIT_RUN_ERROR
+
+ # 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')
+ shutil.copyfile(tempest_conf_old, tempest_conf_file)
+
+ logger.debug("Updating selected tempest.conf parameters...")
+ config = ConfigParser.RawConfigParser()
+ 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()
+ 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 = 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")
+
+ # Get the controller IP from the fuel node
+ cmd = 'sshpass -p %s ssh 2>/dev/null %s %s@%s \
+ \'fuel node --env 1| grep controller | grep "True\| 1" \
+ | awk -F\| "{print \$5}"\'' % (installer_password,
+ ssh_options,
+ installer_username,
+ installer_ip)
+ multisite_controller_ip = "".join(os.popen(cmd).read().split())
+
+ # Login to controller and get bind host details
+ cmd = 'sshpass -p %s ssh 2>/dev/null %s %s@%s "ssh %s \\" \
+ grep -e "^bind_" %s \\""' % (installer_password,
+ ssh_options,
+ installer_username,
+ installer_ip,
+ multisite_controller_ip,
+ kingbird_conf_path)
+ bind_details = os.popen(cmd).read()
+ bind_details = "".join(bind_details.split())
+ # Extract port number from the bind details
+ bind_port = re.findall(r"\D(\d{4})", bind_details)[0]
+ # Extract ip address from the bind details
+ bind_host = re.findall(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}",
+ 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()
+
+ try:
+ config.add_section("kingbird")
+ except Exception:
+ logger.info('kingbird section exist')
+ config.set('kingbird', 'endpoint_type', 'publicURL')
+ config.set('kingbird', 'TIME_TO_SYNC', '20')
+ config.set('kingbird', 'endpoint_url', kingbird_endpoint_url)
+ config.set('kingbird', 'api_version', kingbird_api_version)
+ with open(tempest_conf_file, 'wb') as config_file:
+ config.write(config_file)
+
+ return releng_constants.EXIT_OK
diff --git a/functest/opnfv_tests/openstack/tempest/gen_tempest_conf.py b/functest/opnfv_tests/openstack/tempest/gen_tempest_conf.py
deleted file mode 100755
index 1216a671d..000000000
--- a/functest/opnfv_tests/openstack/tempest/gen_tempest_conf.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (c) 2015 All rights reserved
-# This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Execute Multisite Tempest test cases
-##
-
-import ConfigParser
-import os
-import re
-import shutil
-import functest.utils.functest_utils as ft_utils
-import functest.utils.functest_logger as ft_logger
-from run_tempest import configure_tempest
-from run_tempest import TEMPEST_RESULTS_DIR
-import functest.utils.functest_constants as ft_constants
-
-logger = ft_logger.Logger("gen_tempest_conf").getLogger()
-
-CI_INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
-CI_INSTALLER_IP = ft_constants.CI_INSTALLER_IP
-
-
-def configure_tempest_multisite(deployment_dir):
- """
- Add/update needed parameters into tempest.conf file generated by Rally
- """
- logger.debug("configure the tempest")
- configure_tempest(deployment_dir)
-
- logger.debug("Finding tempest.conf file...")
- 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)
- exit(-1)
-
- # 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')
- shutil.copyfile(tempest_conf_old, tempest_conf_file)
-
- logger.debug("Updating selected tempest.conf parameters...")
- config = ConfigParser.RawConfigParser()
- 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()
- 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")
-
- ssh_options = ("-o UserKnownHostsFile=/dev/null -o "
- "StrictHostKeyChecking=no")
-
- # Get the controller IP from the fuel node
- cmd = 'sshpass -p %s ssh 2>/dev/null %s %s@%s \
- \'fuel node --env 1| grep controller | grep "True\| 1" \
- | awk -F\| "{print \$5}"\'' % (installer_password,
- ssh_options,
- installer_username,
- installer_ip)
- multisite_controller_ip = "".join(os.popen(cmd).read().split())
-
- # Login to controller and get bind host details
- cmd = 'sshpass -p %s ssh 2>/dev/null %s %s@%s "ssh %s \\" \
- grep -e "^bind_" %s \\""' % (installer_password,
- ssh_options,
- installer_username,
- installer_ip,
- multisite_controller_ip,
- kingbird_conf_path)
- bind_details = os.popen(cmd).read()
- bind_details = "".join(bind_details.split())
- # Extract port number from the bind details
- bind_port = re.findall(r"\D(\d{4})", bind_details)[0]
- # Extract ip address from the bind details
- bind_host = re.findall(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}",
- 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()
-
- try:
- config.add_section("kingbird")
- except Exception:
- logger.info('kingbird section exist')
- config.set('kingbird', 'endpoint_type', 'publicURL')
- config.set('kingbird', 'TIME_TO_SYNC', '20')
- config.set('kingbird', 'endpoint_url', kingbird_endpoint_url)
- config.set('kingbird', 'api_version', kingbird_api_version)
- with open(tempest_conf_file, 'wb') as config_file:
- config.write(config_file)
-
- return True
-
-
-def main():
-
- if not os.path.exists(TEMPEST_RESULTS_DIR):
- os.makedirs(TEMPEST_RESULTS_DIR)
-
- deployment_dir = ft_utils.get_deployment_dir()
- configure_tempest_multisite(deployment_dir)
-
-
-if __name__ == '__main__':
- main()
diff --git a/functest/opnfv_tests/openstack/tempest/run_tempest.py b/functest/opnfv_tests/openstack/tempest/run_tempest.py
deleted file mode 100755
index 6406cd193..000000000
--- a/functest/opnfv_tests/openstack/tempest/run_tempest.py
+++ /dev/null
@@ -1,451 +0,0 @@
-#!/usr/bin/env python
-#
-# Description:
-# Runs tempest and pushes the results to the DB
-#
-# Authors:
-# morgan.richomme@orange.com
-# jose.lausuch@ericsson.com
-# viktor.tikkanen@nokia.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 ConfigParser
-import os
-import re
-import shutil
-import subprocess
-import sys
-import time
-
-import argparse
-import yaml
-
-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
-
-modes = ['full', 'smoke', 'baremetal', 'compute', 'data_processing',
- 'identity', 'image', 'network', 'object_storage', 'orchestration',
- 'telemetry', 'volume', 'custom', 'defcore', 'feature_multisite']
-
-""" tests configuration """
-parser = argparse.ArgumentParser()
-parser.add_argument("-d", "--debug",
- help="Debug mode",
- action="store_true")
-parser.add_argument("-s", "--serial",
- help="Run tests in one thread",
- action="store_true")
-parser.add_argument("-m", "--mode",
- help="Tempest test mode [smoke, all]",
- default="smoke")
-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")
-parser.add_argument("-c", "--conf",
- help="User-specified Tempest config file location",
- default="")
-
-args = parser.parse_args()
-
-""" logging configuration """
-logger = ft_logger.Logger("run_tempest").getLogger()
-
-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_FILENAME)
-
-IMAGE_ID_ALT = None
-
-FLAVOR_NAME = ft_constants.FLAVOR_NAME
-FLAVOR_RAM = ft_constants.FLAVOR_RAM
-FLAVOR_DISK = ft_constants.FLAVOR_DISK
-FLAVOR_VCPUS = ft_constants.FLAVOR_VCPUS
-FLAVOR_ID_ALT = None
-
-TEMPEST_PRIVATE_NET_NAME = ft_constants.TEMPEST_PRIVATE_NET_NAME
-TEMPEST_PRIVATE_SUBNET_NAME = ft_constants.TEMPEST_PRIVATE_SUBNET_NAME
-TEMPEST_PRIVATE_SUBNET_CIDR = ft_constants.TEMPEST_PRIVATE_SUBNET_CIDR
-TEMPEST_ROUTER_NAME = ft_constants.TEMPEST_ROUTER_NAME
-TEMPEST_TENANT_NAME = ft_constants.TEMPEST_TENANT_NAME
-TEMPEST_TENANT_DESCRIPTION = ft_constants.TEMPEST_TENANT_DESCRIPTION
-TEMPEST_USER_NAME = ft_constants.TEMPEST_USER_NAME
-TEMPEST_USER_PASSWORD = ft_constants.TEMPEST_USER_PASSWORD
-TEMPEST_SSH_TIMEOUT = ft_constants.TEMPEST_SSH_TIMEOUT
-TEMPEST_USE_CUSTOM_IMAGES = ft_constants.TEMPEST_USE_CUSTOM_IMAGES
-TEMPEST_USE_CUSTOM_FLAVORS = ft_constants.TEMPEST_USE_CUSTOM_FLAVORS
-
-RESULTS_DIR = ft_constants.FUNCTEST_RESULTS_DIR
-TEMPEST_RESULTS_DIR = os.path.join(RESULTS_DIR, 'tempest')
-
-REPO_PATH = ft_constants.FUNCTEST_REPO_DIR
-TEMPEST_TEST_LIST_DIR = ft_constants.TEMPEST_TEST_LIST_DIR
-TEMPEST_CUSTOM = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR,
- 'test_list.txt')
-TEMPEST_BLACKLIST = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR,
- 'blacklist.txt')
-TEMPEST_DEFCORE = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR,
- 'defcore_req.txt')
-TEMPEST_RAW_LIST = os.path.join(TEMPEST_RESULTS_DIR, 'test_raw_list.txt')
-TEMPEST_LIST = os.path.join(TEMPEST_RESULTS_DIR, 'test_list.txt')
-
-
-class GlobalVariables:
- IMAGE_ID = None
- FLAVOR_ID = None
- MODE = "smoke"
-
-
-def get_info(file_result):
- test_run = ""
- duration = ""
- test_failed = ""
-
- p = subprocess.Popen('cat tempest.log',
- shell=True, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- for line in p.stdout.readlines():
- # print line,
- if (len(test_run) < 1):
- test_run = re.findall("[0-9]*\.[0-9]*s", line)
- if (len(duration) < 1):
- duration = re.findall("[0-9]*\ tests", line)
- regexp = r"(failures=[0-9]+)"
- if (len(test_failed) < 1):
- test_failed = re.findall(regexp, line)
-
- logger.debug("test_run:" + test_run)
- logger.debug("duration:" + duration)
-
-
-def create_tempest_resources():
- keystone_client = os_utils.get_keystone_client()
-
- logger.debug("Creating tenant and user for Tempest suite")
- tenant_id = os_utils.create_tenant(keystone_client,
- TEMPEST_TENANT_NAME,
- TEMPEST_TENANT_DESCRIPTION)
- if not tenant_id:
- logger.error("Error : Failed to create %s tenant"
- % TEMPEST_TENANT_NAME)
-
- user_id = os_utils.create_user(keystone_client, TEMPEST_USER_NAME,
- TEMPEST_USER_PASSWORD,
- None, tenant_id)
- if not user_id:
- logger.error("Error : Failed to create %s user" % TEMPEST_USER_NAME)
-
- logger.debug("Creating private network for Tempest suite")
- network_dic = \
- os_utils.create_shared_network_full(TEMPEST_PRIVATE_NET_NAME,
- TEMPEST_PRIVATE_SUBNET_NAME,
- TEMPEST_ROUTER_NAME,
- TEMPEST_PRIVATE_SUBNET_CIDR)
- if not network_dic:
- exit(1)
-
- if TEMPEST_USE_CUSTOM_IMAGES:
- # adding alternative image should be trivial should we need it
- logger.debug("Creating image for Tempest suite")
- _, GlobalVariables.IMAGE_ID = os_utils.get_or_create_image(
- GLANCE_IMAGE_NAME, GLANCE_IMAGE_PATH, GLANCE_IMAGE_FORMAT)
- if not GlobalVariables.IMAGE_ID:
- exit(-1)
-
- if TEMPEST_USE_CUSTOM_FLAVORS:
- # adding alternative flavor should be trivial should we need it
- logger.debug("Creating flavor for Tempest suite")
- _, GlobalVariables.FLAVOR_ID = os_utils.get_or_create_flavor(
- FLAVOR_NAME, FLAVOR_RAM, FLAVOR_DISK, FLAVOR_VCPUS)
- if not GlobalVariables.FLAVOR_ID:
- exit(-1)
-
-
-def configure_tempest(deployment_dir):
- """
- Add/update needed parameters into tempest.conf file generated by Rally
- """
-
- tempest_conf_file = 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"
- ft_utils.execute_command(cmd)
-
- logger.debug("Finding tempest.conf file...")
- if not os.path.isfile(tempest_conf_file):
- logger.error("Tempest configuration file %s NOT found."
- % tempest_conf_file)
- exit(-1)
-
- logger.debug("Updating selected tempest.conf parameters...")
- config = ConfigParser.RawConfigParser()
- config.read(tempest_conf_file)
- config.set('compute', 'fixed_network_name', TEMPEST_PRIVATE_NET_NAME)
- if TEMPEST_USE_CUSTOM_IMAGES:
- if GlobalVariables.IMAGE_ID is not None:
- config.set('compute', 'image_ref', GlobalVariables.IMAGE_ID)
- if IMAGE_ID_ALT is not None:
- config.set('compute', 'image_ref_alt', IMAGE_ID_ALT)
- if TEMPEST_USE_CUSTOM_FLAVORS:
- if GlobalVariables.FLAVOR_ID is not None:
- config.set('compute', 'flavor_ref', GlobalVariables.FLAVOR_ID)
- if FLAVOR_ID_ALT is not None:
- config.set('compute', 'flavor_ref_alt', FLAVOR_ID_ALT)
- config.set('identity', 'tenant_name', TEMPEST_TENANT_NAME)
- config.set('identity', 'username', TEMPEST_USER_NAME)
- config.set('identity', 'password', TEMPEST_USER_PASSWORD)
- config.set('validation', 'ssh_timeout', TEMPEST_SSH_TIMEOUT)
-
- if ft_constants.OS_ENDPOINT_TYPE is not None:
- services_list = ['compute', 'volume', 'image', 'network',
- 'data-processing', 'object-storage', 'orchestration']
- sections = config.sections()
- for service in services_list:
- if service not in sections:
- config.add_section(service)
- config.set(service, 'endpoint_type',
- ft_constants.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')
- return True
-
-
-def read_file(filename):
- with open(filename) as src:
- return [line.strip() for line in src.readlines()]
-
-
-def generate_test_list(deployment_dir, mode):
- logger.debug("Generating test case list...")
- if mode == 'defcore':
- shutil.copyfile(TEMPEST_DEFCORE, TEMPEST_RAW_LIST)
- elif mode == 'custom':
- if os.path.isfile(TEMPEST_CUSTOM):
- shutil.copyfile(TEMPEST_CUSTOM, TEMPEST_RAW_LIST)
- else:
- logger.error("Tempest test list file %s NOT found."
- % TEMPEST_CUSTOM)
- exit(-1)
- else:
- if mode == 'smoke':
- testr_mode = "smoke"
- elif mode == 'feature_multisite':
- testr_mode = " | grep -i kingbird "
- elif mode == 'full':
- testr_mode = ""
- else:
- testr_mode = 'tempest.api.' + mode
- cmd = ("cd " + deployment_dir + ";" + "testr list-tests " +
- testr_mode + ">" + TEMPEST_RAW_LIST + ";cd")
- ft_utils.execute_command(cmd)
-
-
-def apply_tempest_blacklist():
- logger.debug("Applying tempest blacklist...")
- cases_file = read_file(TEMPEST_RAW_LIST)
- result_file = open(TEMPEST_LIST, 'w')
- black_tests = []
- try:
- installer_type = ft_constants.CI_INSTALLER_TYPE
- deploy_scenario = ft_constants.CI_SCENARIO
- if (bool(installer_type) * bool(deploy_scenario)):
- # if INSTALLER_TYPE and DEPLOY_SCENARIO are set we read the file
- black_list_file = open(TEMPEST_BLACKLIST)
- black_list_yaml = yaml.safe_load(black_list_file)
- black_list_file.close()
- for item in black_list_yaml:
- scenarios = item['scenarios']
- installers = item['installers']
- if (deploy_scenario in scenarios and
- installer_type in installers):
- tests = item['tests']
- for test in tests:
- black_tests.append(test)
- break
- except:
- black_tests = []
- logger.debug("Tempest blacklist file does not exist.")
-
- for cases_line in cases_file:
- for black_tests_line in black_tests:
- if black_tests_line in cases_line:
- break
- else:
- result_file.write(str(cases_line) + '\n')
- result_file.close()
-
-
-def run_tempest(OPTION):
- #
- # the "main" function of the script which launches Rally to run Tempest
- # :param option: tempest option (smoke, ..)
- # :return: void
- #
- logger.info("Starting Tempest test suite: '%s'." % OPTION)
- start_time = time.time()
- stop_time = start_time
- cmd_line = "rally verify start " + OPTION + " --system-wide"
-
- 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,
- time.strftime("%a %b %d %H:%M:%S %Z %Y")))
-
- f_stdout = open(TEMPEST_RESULTS_DIR + "/tempest.log", 'w+')
- f_stderr = open(TEMPEST_RESULTS_DIR + "/tempest-error.log", 'w+')
- f_env = open(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,
- stderr=f_stderr,
- bufsize=1)
-
- with p.stdout:
- for line in iter(p.stdout.readline, b''):
- if re.search("\} tempest\.", line):
- logger.info(line.replace('\n', ''))
- f_stdout.write(line)
- p.wait()
-
- f_stdout.close()
- f_stderr.close()
- f_env.close()
-
- cmd_line = "rally verify show"
- output = ""
- p = subprocess.Popen(
- cmd_line, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- for line in p.stdout:
- if re.search("Tests\:", 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]
- time_start = output[6]
- 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
- stop_time = time.time()
-
- try:
- diff = (int(num_tests) - int(num_failures))
- success_rate = 100 * diff / int(num_tests)
- except:
- success_rate = 0
-
- if 'smoke' in args.mode:
- case_name = 'tempest_smoke_serial'
- elif 'feature' in args.mode:
- case_name = args.mode.replace("feature_", "")
- else:
- case_name = 'tempest_full_parallel'
-
- status = ft_utils.check_success_rate(case_name, success_rate)
- logger.info("Tempest %s success_rate is %s%%, is marked as %s"
- % (case_name, success_rate, status))
-
- # Push results in payload of testcase
- if args.report:
- # add the test in error in the details sections
- # should be possible to do it during the test
- logger.debug("Pushing tempest results into DB...")
- with open(TEMPEST_RESULTS_DIR + "/tempest.log", 'r') as myfile:
- output = myfile.read()
- error_logs = ""
-
- for match in re.findall('(.*?)[. ]*FAILED', output):
- error_logs += match
-
- # Generate json results for DB
- json_results = {"timestart": time_start, "duration": dur_sec_int,
- "tests": int(num_tests), "failures": int(num_failures),
- "errors": error_logs}
- logger.info("Results: " + str(json_results))
- # split Tempest smoke and full
-
- try:
- ft_utils.push_results_to_db("functest",
- case_name,
- start_time,
- stop_time,
- status,
- json_results)
- except:
- logger.error("Error pushing results into Database '%s'"
- % sys.exc_info()[0])
-
- if status == "PASS":
- return 0
- else:
- return -1
-
-
-def main():
-
- if not (args.mode in modes):
- logger.error("Tempest mode not valid. "
- "Possible values are:\n" + str(modes))
- exit(-1)
-
- if not os.path.exists(TEMPEST_RESULTS_DIR):
- os.makedirs(TEMPEST_RESULTS_DIR)
-
- deployment_dir = ft_utils.get_deployment_dir()
- create_tempest_resources()
-
- if "" == args.conf:
- GlobalVariables.MODE = ""
- configure_tempest(deployment_dir)
- else:
- GlobalVariables.MODE = " --tempest-config " + args.conf
-
- generate_test_list(deployment_dir, args.mode)
- apply_tempest_blacklist()
-
- GlobalVariables.MODE += " --tests-file " + TEMPEST_LIST
- if args.serial:
- GlobalVariables.MODE += " --concur 1"
-
- ret_val = run_tempest(GlobalVariables.MODE)
- if ret_val != 0:
- sys.exit(-1)
-
- sys.exit(0)
-
-
-if __name__ == '__main__':
- main()
diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py
new file mode 100644
index 000000000..20b1ebb4c
--- /dev/null
+++ b/functest/opnfv_tests/openstack/tempest/tempest.py
@@ -0,0 +1,331 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2015 All rights reserved
+# This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+
+import os
+import re
+import shutil
+import subprocess
+import time
+
+import yaml
+
+import conf_utils
+import functest.core.testcase_base as testcase_base
+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
+
+""" logging configuration """
+logger = ft_logger.Logger("Tempest").getLogger()
+
+
+class TempestCommon(testcase_base.TestcaseBase):
+
+ def __init__(self):
+ super(TempestCommon, self).__init__()
+ self.MODE = ""
+ self.OPTION = ""
+ self.FLAVOR_ID = None
+ self.IMAGE_ID = None
+ self.DEPLOYMENT_DIR = self.get_deployment_dir()
+
+ @staticmethod
+ def get_deployment_dir():
+ """
+ Returns current Rally deployment directory
+ """
+ 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.")
+ exit(-1)
+ return os.path.join(CONST.dir_rally_inst,
+ "tempest/for-deployment-" + deployment_uuid)
+
+ @staticmethod
+ def read_file(filename):
+ with open(filename) as src:
+ return [line.strip() for line in src.readlines()]
+
+ def create_tempest_resources(self):
+ keystone_client = os_utils.get_keystone_client()
+
+ logger.debug("Creating tenant and user for Tempest suite")
+ tenant_id = os_utils.create_tenant(
+ keystone_client,
+ CONST.tempest_identity_tenant_name,
+ CONST.tempest_identity_tenant_description)
+ if not tenant_id:
+ logger.error("Error : Failed to create %s tenant"
+ % CONST.tempest_identity_tenant_name)
+
+ user_id = os_utils.create_user(keystone_client,
+ 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" %
+ CONST.tempest_identity_user_name)
+
+ logger.debug("Creating private network for Tempest suite")
+ 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 testcase_base.TestcaseBase.EX_RUN_ERROR
+
+ 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(
+ CONST.openstack_image_name, conf_utils.GLANCE_IMAGE_PATH,
+ CONST.openstack_image_disk_format)
+ if not self.IMAGE_ID:
+ return testcase_base.TestcaseBase.EX_RUN_ERROR
+
+ 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(
+ CONST.openstack_flavor_name,
+ CONST.openstack_flavor_ram,
+ CONST.openstack_flavor_disk,
+ CONST.openstack_flavor_vcpus)
+ if not self.FLAVOR_ID:
+ return testcase_base.TestcaseBase.EX_RUN_ERROR
+
+ return testcase_base.TestcaseBase.EX_OK
+
+ def generate_test_list(self, DEPLOYMENT_DIR):
+ logger.debug("Generating test case list...")
+ if self.MODE == 'defcore':
+ shutil.copyfile(
+ conf_utils.TEMPEST_DEFCORE, conf_utils.TEMPEST_RAW_LIST)
+ elif self.MODE == 'custom':
+ if os.path.isfile(conf_utils.TEMPEST_CUSTOM):
+ shutil.copyfile(
+ conf_utils.TEMPEST_CUSTOM, conf_utils.TEMPEST_RAW_LIST)
+ else:
+ logger.error("Tempest test list file %s NOT found."
+ % conf_utils.TEMPEST_CUSTOM)
+ return testcase_base.TestcaseBase.EX_RUN_ERROR
+ else:
+ if self.MODE == 'smoke':
+ testr_mode = "smoke"
+ elif self.MODE == 'feature_multisite':
+ testr_mode = " | grep -i kingbird "
+ elif self.MODE == 'full':
+ testr_mode = ""
+ else:
+ testr_mode = 'tempest.api.' + self.MODE
+ cmd = ("cd " + DEPLOYMENT_DIR + ";" + "testr list-tests " +
+ testr_mode + ">" + conf_utils.TEMPEST_RAW_LIST + ";cd")
+ ft_utils.execute_command(cmd)
+
+ return testcase_base.TestcaseBase.EX_OK
+
+ def apply_tempest_blacklist(self):
+ logger.debug("Applying tempest blacklist...")
+ cases_file = self.read_file(conf_utils.TEMPEST_RAW_LIST)
+ result_file = open(conf_utils.TEMPEST_LIST, 'w')
+ black_tests = []
+ try:
+ 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
+ black_list_file = open(conf_utils.TEMPEST_BLACKLIST)
+ black_list_yaml = yaml.safe_load(black_list_file)
+ black_list_file.close()
+ for item in black_list_yaml:
+ scenarios = item['scenarios']
+ installers = item['installers']
+ if (deploy_scenario in scenarios and
+ installer_type in installers):
+ tests = item['tests']
+ for test in tests:
+ black_tests.append(test)
+ break
+ except:
+ black_tests = []
+ logger.debug("Tempest blacklist file does not exist.")
+
+ for cases_line in cases_file:
+ for black_tests_line in black_tests:
+ if black_tests_line in cases_line:
+ break
+ else:
+ result_file.write(str(cases_line) + '\n')
+ result_file.close()
+ return testcase_base.TestcaseBase.EX_OK
+
+ 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.DEPLOYMENT_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.OPTION += (" --tests-file %s " % conf_utils.TEMPEST_LIST)
+
+ cmd_line = "rally verify start " + self.OPTION + " --system-wide"
+ 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" %
+ (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_stderr = open(
+ conf_utils.TEMPEST_RESULTS_DIR + "/tempest-error.log", 'w+')
+ f_env = open(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,
+ stderr=f_stderr,
+ bufsize=1)
+
+ with p.stdout:
+ for line in iter(p.stdout.readline, b''):
+ if re.search("\} tempest\.", line):
+ logger.info(line.replace('\n', ''))
+ f_stdout.write(line)
+ p.wait()
+
+ f_stdout.close()
+ f_stderr.close()
+ f_env.close()
+
+ cmd_line = "rally verify show"
+ output = ""
+ p = subprocess.Popen(cmd_line,
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ for line in p.stdout:
+ if re.search("Tests\:", 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
+
+ try:
+ diff = (int(num_tests) - int(num_failures))
+ success_rate = 100 * diff / int(num_tests)
+ except:
+ success_rate = 0
+
+ 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, self.criteria))
+
+ self.stop_time = time.time()
+
+ if self.criteria == "PASS":
+ return testcase_base.TestcaseBase.EX_OK
+ else:
+ return testcase_base.TestcaseBase.EX_TESTCASE_FAILED
+
+
+class TempestSmokeSerial(TempestCommon):
+
+ def __init__(self):
+ TempestCommon.__init__(self)
+ self.case_name = "tempest_smoke_serial"
+ self.MODE = "smoke"
+ self.OPTION = "--concur 1"
+
+
+class TempestSmokeParallel(TempestCommon):
+
+ def __init__(self):
+ TempestCommon.__init__(self)
+ self.case_name = "tempest_smoke_parallel"
+ self.MODE = "smoke"
+ self.OPTION = ""
+
+
+class TempestFullParallel(TempestCommon):
+
+ def __init__(self):
+ TempestCommon.__init__(self)
+ self.case_name = "tempest_full_parallel"
+ self.MODE = "full"
+
+
+class TempestMultisite(TempestCommon):
+
+ def __init__(self):
+ TempestCommon.__init__(self)
+ self.case_name = "multisite"
+ self.MODE = "feature_multisite"
+ self.OPTION = "--concur 1"
+ conf_utils.configure_tempest_multisite(logger, self.DEPLOYMENT_DIR)
+
+
+class TempestCustom(TempestCommon):
+
+ def __init__(self, mode, option):
+ TempestCommon.__init__(self)
+ self.case_name = "tempest_custom"
+ self.MODE = mode
+ self.OPTION = option
diff --git a/functest/opnfv_tests/openstack/vping/vping_base.py b/functest/opnfv_tests/openstack/vping/vping_base.py
index 213b79fcf..a5309bd44 100644..100755
--- a/functest/opnfv_tests/openstack/vping/vping_base.py
+++ b/functest/opnfv_tests/openstack/vping/vping_base.py
@@ -12,43 +12,38 @@ import pprint
import time
from datetime import datetime
-import functest.utils.functest_utils as ft_utils
-import functest.utils.functest_constants as ft_constants
-import functest.utils.openstack_utils as os_utils
import functest.core.testcase_base as testcase_base
+import functest.utils.openstack_utils as os_utils
+from functest.utils.constants import CONST
class VPingBase(testcase_base.TestcaseBase):
def __init__(self):
- def get_conf(parameter):
- return ft_utils.get_functest_config(parameter)
-
super(VPingBase, self).__init__()
self.logger = None
- self.functest_repo = ft_constants.FUNCTEST_REPO_DIR
- self.repo = get_conf('general.directories.dir_vping')
- self.vm1_name = get_conf('vping.vm_name_1')
- self.vm2_name = get_conf('vping.vm_name_2')
+ self.functest_repo = CONST.dir_repo_functest
+ self.repo = CONST.dir_vping
+ self.vm1_name = CONST.vping_vm_name_1
+ self.vm2_name = CONST.vping_vm_name_2
self.vm_boot_timeout = 180
self.vm_delete_timeout = 100
- self.ping_timeout = get_conf('vping.ping_timeout')
+ self.ping_timeout = CONST.vping_ping_timeout
- self.image_name = get_conf('vping.image_name')
- self.image_filename = get_conf('general.openstack.image_file_name')
- self.image_format = get_conf('general.openstack.image_disk_format')
- self.image_path = \
- "%s/%s" % (get_conf('general.directories.dir_functest_data'),
- self.image_filename)
+ self.image_name = CONST.vping_image_name
+ self.image_filename = CONST.openstack_image_file_name
+ self.image_format = CONST.openstack_image_disk_format
+ self.image_path = os.path.join(CONST.dir_functest_data,
+ self.image_filename)
- self.flavor_name = get_conf('vping.vm_flavor')
+ self.flavor_name = CONST.vping_vm_flavor
# NEUTRON Private Network parameters
- self.private_net_name = get_conf('vping.vping_private_net_name')
- self.private_subnet_name = get_conf('vping.vping_private_subnet_name')
- self.private_subnet_cidr = get_conf('vping.vping_private_subnet_cidr')
- self.router_name = get_conf('vping.vping_router_name')
- self.sg_name = get_conf('vping.vping_sg_name')
- self.sg_desc = get_conf('vping.vping_sg_descr')
+ self.private_net_name = CONST.vping_private_net_name
+ self.private_subnet_name = CONST.vping_private_subnet_name
+ self.private_subnet_cidr = CONST.vping_private_subnet_cidr
+ self.router_name = CONST.vping_router_name
+ self.sg_name = CONST.vping_sg_name
+ self.sg_desc = CONST.vping_sg_desc
self.neutron_client = os_utils.get_neutron_client()
self.glance_client = os_utils.get_glance_client()
self.nova_client = os_utils.get_nova_client()
diff --git a/functest/opnfv_tests/openstack/vping/vping_ssh.py b/functest/opnfv_tests/openstack/vping/vping_ssh.py
index 8ae590eda..b032c3087 100644..100755
--- a/functest/opnfv_tests/openstack/vping/vping_ssh.py
+++ b/functest/opnfv_tests/openstack/vping/vping_ssh.py
@@ -101,9 +101,9 @@ class VPingSSH(vping_base.VPingBase):
"from the dhcp agent." % self.vm2_name)
# if dhcp not work,it shows "No lease, failing".The test will fail
- if "No lease, failing" in console_log \
- and not nolease \
- and not got_ip:
+ if ("No lease, failing" in console_log and
+ not nolease and
+ not got_ip):
nolease = True
self.logger.debug("Console-log '%s': No lease, failing..."
% self.vm2_name)
diff --git a/functest/opnfv_tests/openstack/vping/vping_userdata.py b/functest/opnfv_tests/openstack/vping/vping_userdata.py
index fa91c12a6..fa91c12a6 100644..100755
--- a/functest/opnfv_tests/openstack/vping/vping_userdata.py
+++ b/functest/opnfv_tests/openstack/vping/vping_userdata.py
diff --git a/functest/opnfv_tests/sdn/odl/odl.py b/functest/opnfv_tests/sdn/odl/odl.py
index 95440746c..0905e55cc 100755
--- a/functest/opnfv_tests/sdn/odl/odl.py
+++ b/functest/opnfv_tests/sdn/odl/odl.py
@@ -20,10 +20,9 @@ from robot.errors import RobotError
import robot.run
from robot.utils.robottime import timestamp_to_secs
-import functest.core.testcase_base as testcase_base
+from functest.core import testcase_base
import functest.utils.functest_logger as ft_logger
import functest.utils.openstack_utils as op_utils
-import functest.utils.functest_constants as ft_constants
class ODLResultVisitor(ResultVisitor):
@@ -36,7 +35,7 @@ class ODLResultVisitor(ResultVisitor):
output['name'] = test.name
output['parent'] = test.parent.name
output['status'] = test.status
- output['startime'] = test.starttime
+ output['starttime'] = test.starttime
output['endtime'] = test.endtime
output['critical'] = test.critical
output['text'] = test.message
@@ -49,17 +48,17 @@ class ODLResultVisitor(ResultVisitor):
class ODLTests(testcase_base.TestcaseBase):
- repos = ft_constants.REPOS_DIR
+ repos = "/home/opnfv/repos/"
odl_test_repo = os.path.join(repos, "odl_test")
neutron_suite_dir = os.path.join(odl_test_repo,
"csit/suites/openstack/neutron")
basic_suite_dir = os.path.join(odl_test_repo,
"csit/suites/integration/basic")
- res_dir = os.path.join(ft_constants.FUNCTEST_RESULTS_DIR, "odl")
-
+ res_dir = '/home/opnfv/functest/results/odl/'
logger = ft_logger.Logger("opendaylight").getLogger()
def __init__(self):
+ testcase_base.TestcaseBase.__init__(self)
self.case_name = "odl"
@classmethod
@@ -79,8 +78,8 @@ class ODLTests(testcase_base.TestcaseBase):
return False
def parse_results(self):
- output_dir = os.path.join(self.res_dir, 'output.xml')
- result = ExecutionResult(output_dir)
+ xml_file = os.path.join(self.res_dir, 'output.xml')
+ result = ExecutionResult(xml_file)
visitor = ODLResultVisitor()
result.visit(visitor)
self.criteria = result.suite.status
@@ -89,7 +88,6 @@ class ODLTests(testcase_base.TestcaseBase):
self.details = {}
self.details['description'] = result.suite.name
self.details['tests'] = visitor.get_data()
- return self.criteria
def main(self, **kwargs):
dirs = [self.basic_suite_dir, self.neutron_suite_dir]
@@ -128,10 +126,8 @@ class ODLTests(testcase_base.TestcaseBase):
self.logger.info("\n" + stdout.read())
self.logger.info("ODL results were successfully generated")
try:
- test_res = self.parse_results()
+ self.parse_results()
self.logger.info("ODL results were successfully parsed")
- if test_res is not "PASS":
- return self.EX_RUN_ERROR
except RobotError as e:
self.logger.error("Run tests before publishing: %s" %
e.message)
@@ -146,11 +142,8 @@ class ODLTests(testcase_base.TestcaseBase):
def run(self):
try:
- kclient = op_utils.get_keystone_client()
- keystone_url = kclient.service_catalog.url_for(
- service_type='identity', endpoint_type='publicURL')
- neutron_url = kclient.service_catalog.url_for(
- service_type='network', endpoint_type='publicURL')
+ keystone_url = op_utils.get_endpoint(service_type='identity')
+ neutron_url = op_utils.get_endpoint(service_type='network')
kwargs = {'keystoneip': urlparse.urlparse(keystone_url).hostname}
kwargs['neutronip'] = urlparse.urlparse(neutron_url).hostname
kwargs['odlip'] = kwargs['neutronip']
@@ -158,29 +151,23 @@ class ODLTests(testcase_base.TestcaseBase):
kwargs['odlrestconfport'] = '8181'
kwargs['odlusername'] = 'admin'
kwargs['odlpassword'] = 'admin'
-
- installer_type = ft_constants.CI_INSTALLER_TYPE
- kwargs['osusername'] = ft_constants.OS_USERNAME
- kwargs['ostenantname'] = ft_constants.OS_TENANT_NAME
- kwargs['ospassword'] = ft_constants.OS_PASSWORD
-
+ installer_type = None
+ if 'INSTALLER_TYPE' in os.environ:
+ installer_type = os.environ['INSTALLER_TYPE']
+ kwargs['osusername'] = os.environ['OS_USERNAME']
+ kwargs['ostenantname'] = os.environ['OS_TENANT_NAME']
+ kwargs['ospassword'] = os.environ['OS_PASSWORD']
if installer_type == 'fuel':
kwargs['odlwebport'] = '8282'
elif installer_type == 'apex':
- if ft_constants.SDN_CONTROLLER_IP is None:
- return self.EX_RUN_ERROR
- kwargs['odlip'] = ft_constants.SDN_CONTROLLER_IP
+ kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
kwargs['odlwebport'] = '8181'
elif installer_type == 'joid':
- if ft_constants.SDN_CONTROLLER is None:
- return self.EX_RUN_ERROR
- kwargs['odlip'] = ft_constants.SDN_CONTROLLER
+ kwargs['odlip'] = os.environ['SDN_CONTROLLER']
elif installer_type == 'compass':
kwargs['odlwebport'] = '8181'
else:
- if ft_constants.SDN_CONTROLLER_IP is None:
- return self.EX_RUN_ERROR
- kwargs['odlip'] = ft_constants.SDN_CONTROLLER_IP
+ kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
except KeyError as e:
self.logger.error("Cannot run ODL testcases. "
"Please check env var: "
diff --git a/functest/opnfv_tests/sdn/onos/sfc/sfc_onos.py b/functest/opnfv_tests/sdn/onos/sfc/sfc_onos.py
index 8ca32e9bb..349b42a88 100644
--- a/functest/opnfv_tests/sdn/onos/sfc/sfc_onos.py
+++ b/functest/opnfv_tests/sdn/onos/sfc/sfc_onos.py
@@ -1,4 +1,4 @@
-import os
+import os
import re
import time
import json
diff --git a/functest/opnfv_tests/vnf/ims/vims.py b/functest/opnfv_tests/vnf/ims/vims.py
index fe888b698..15981f512 100755
--- a/functest/opnfv_tests/vnf/ims/vims.py
+++ b/functest/opnfv_tests/vnf/ims/vims.py
@@ -19,10 +19,7 @@ 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
@@ -242,17 +239,15 @@ def main():
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")
+ creds = os_utils.get_credentials()
logger.info("Prepare OpenStack plateform (create tenant and user)")
- keystone = ksclient.Client(**ks_creds)
+ keystone = os_utils.get_keystone_client()
- user_id = os_utils.get_user_id(keystone, ks_creds['username'])
+ user_id = os_utils.get_user_id(keystone, creds['username'])
if user_id == '':
step_failure("init", "Error : Failed to get id of " +
- ks_creds['username'])
+ creds['username'])
tenant_id = os_utils.create_tenant(
keystone, VIMS_TENANT_NAME, VIMS_TENANT_DESCRIPTION)
@@ -271,7 +266,7 @@ def main():
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'])
+ creds['username'])
user_id = os_utils.create_user(
keystone, VIMS_TENANT_NAME, VIMS_TENANT_NAME, None, tenant_id)
@@ -279,18 +274,10 @@ def main():
logger.error("Error : Failed to create %s user" % VIMS_TENANT_NAME)
logger.info("Update OpenStack creds informations")
- ks_creds.update({
+ 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,
+ "tenant": VIMS_TENANT_NAME,
})
logger.info("Upload some OS images if it doesn't exist")
@@ -314,10 +301,8 @@ def main():
"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)
+ neutron = os_utils.get_neutron_client(creds)
if not os_utils.update_sg_quota(neutron, tenant_id, 50, 100):
step_failure(
"init",
@@ -325,17 +310,22 @@ def main():
VIMS_TENANT_NAME)
# ############### CLOUDIFY INITIALISATION ################
- public_auth_url = keystone.service_catalog.url_for(
- service_type='identity', endpoint_type='publicURL')
+ public_auth_url = os_utils.get_endpoint('identity')
cfy = Orchestrator(VIMS_DATA_DIR, CFY_INPUTS)
- cfy.set_credentials(username=ks_creds['username'], password=ks_creds[
- 'password'], tenant_name=ks_creds['tenant_name'],
+ if 'tenant_name' in creds.keys():
+ tenant_name = creds['tenant_name']
+ elif 'project_name' in creds.keys():
+ tenant_name = creds['project_name']
+
+ cfy.set_credentials(username=creds['username'],
+ password=creds['password'],
+ tenant_name=tenant_name,
auth_url=public_auth_url)
logger.info("Collect flavor id for cloudify manager server")
- nova = nvclient.Client("2", **nv_creds)
+ nova = os_utils.get_nova_client(creds)
flavor_name = "m1.large"
flavor_id = os_utils.get_flavor_id(nova, flavor_name)
@@ -416,7 +406,6 @@ def main():
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)
@@ -490,10 +479,6 @@ def main():
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'])
diff --git a/functest/tests/unit/cli/__init__.py b/functest/tests/unit/cli/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/tests/unit/cli/__init__.py
diff --git a/functest/tests/unit/cli/commands/__init__.py b/functest/tests/unit/cli/commands/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/tests/unit/cli/commands/__init__.py
diff --git a/functest/tests/unit/cli/commands/test_cli_env.py b/functest/tests/unit/cli/commands/test_cli_env.py
new file mode 100644
index 000000000..4b6ea57a7
--- /dev/null
+++ b/functest/tests/unit/cli/commands/test_cli_env.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import logging
+import unittest
+
+from git.exc import NoSuchPathError
+import mock
+
+from functest.cli.commands import cli_env
+from functest.utils.constants import CONST
+from functest.tests.unit import test_utils
+
+
+class CliEnvTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.cli_environ = cli_env.CliEnv()
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_prepare_default(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/prepare_env.py start" %
+ CONST.dir_repo_functest)
+ self.cli_environ.prepare()
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_prepare_missing_status(self, mock_ft_utils, mock_os):
+ with mock.patch('__builtin__.raw_input', return_value="y"), \
+ mock.patch('functest.cli.commands.cli_testcase.os.remove') \
+ as mock_os_remove:
+ cmd = ("python %s/functest/ci/prepare_env.py start" %
+ CONST.dir_repo_functest)
+ self.cli_environ.prepare()
+ mock_os_remove.assert_called_once_with(CONST.env_active)
+ mock_ft_utils.assert_called_with(cmd)
+
+ def _test_show_missing_env_var(self, var, *args):
+ if var == 'INSTALLER_TYPE':
+ CONST.INSTALLER_TYPE = None
+ reg_string = "| INSTALLER: Unknown, \S+\s*|"
+ elif var == 'INSTALLER_IP':
+ CONST.INSTALLER_IP = None
+ reg_string = "| INSTALLER: \S+, Unknown\s*|"
+ elif var == 'SCENARIO':
+ CONST.DEPLOY_SCENARIO = None
+ reg_string = "| SCENARIO: Unknown\s*|"
+ elif var == 'NODE':
+ CONST.NODE_NAME = None
+ reg_string = "| POD: Unknown\s*|"
+ elif var == 'BUILD_TAG':
+ CONST.BUILD_TAG = None
+ reg_string = "| BUILD TAG: None|"
+ elif var == 'DEBUG':
+ CONST.CI_DEBUG = None
+ reg_string = "| DEBUG FLAG: false\s*|"
+ elif var == 'STATUS':
+ reg_string = "| STATUS: not ready\s*|"
+
+ with mock.patch('functest.cli.commands.cli_env.click.echo') \
+ as mock_click_echo:
+ self.cli_environ.show()
+ mock_click_echo.assert_called_with(test_utils.
+ RegexMatch(reg_string))
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_installer_type(self, *args):
+ self._test_show_missing_env_var('INSTALLER_TYPE', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_installer_ip(self, *args):
+ self._test_show_missing_env_var('INSTALLER_IP', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_scenario(self, *args):
+ self._test_show_missing_env_var('SCENARIO', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_node(self, *args):
+ self._test_show_missing_env_var('NODE', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_build_tag(self, *args):
+ self._test_show_missing_env_var('BUILD_TAG', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ def test_show_missing_ci_debug(self, *args):
+ self._test_show_missing_env_var('DEBUG', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.git.Repo')
+ @mock.patch('functest.cli.commands.cli_env.os.path.isfile',
+ return_value=False)
+ def test_show_missing_environment(self, *args):
+ self._test_show_missing_env_var('STATUS', *args)
+
+ @mock.patch('functest.cli.commands.cli_env.os.path.exists',
+ return_value=False)
+ def test_show_missing_git_repo_dir(self, *args):
+ CONST.dir_repo_functest = None
+ self.assertRaises(NoSuchPathError, lambda: self.cli_environ.show())
+
+ @mock.patch('functest.cli.commands.cli_env.click.echo')
+ @mock.patch('functest.cli.commands.cli_env.os.path.isfile',
+ return_value=True)
+ def test_status_environment_present(self, mock_path, mock_click_echo):
+ self.assertEqual(self.cli_environ.status(), 0)
+ mock_click_echo.assert_called_with("Functest environment"
+ " ready to run tests.\n")
+
+ @mock.patch('functest.cli.commands.cli_env.click.echo')
+ @mock.patch('functest.cli.commands.cli_env.os.path.isfile',
+ return_value=False)
+ def test_status_environment_absent(self, mock_path, mock_click_echo):
+ self.assertEqual(self.cli_environ.status(), 1)
+ mock_click_echo.assert_called_with("Functest environment"
+ " is not installed.\n")
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/commands/test_cli_os.py b/functest/tests/unit/cli/commands/test_cli_os.py
new file mode 100644
index 000000000..9e704806b
--- /dev/null
+++ b/functest/tests/unit/cli/commands/test_cli_os.py
@@ -0,0 +1,238 @@
+#!/usr/bin/env python
+#
+# jose.lausuch@ericsson.com
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+
+import logging
+import unittest
+import os
+
+import mock
+
+from functest.cli.commands import cli_os
+from functest.utils.constants import CONST
+
+
+class CliOpenStackTesting(unittest.TestCase):
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.endpoint_ip = 'test_ip'
+ self.os_auth_url = 'http://test_ip:test_port/v2.0'
+ self.installer_type = 'test_installer_type'
+ self.installer_ip = 'test_installer_ip'
+ self.openstack_creds = 'test_openstack_creds'
+ self.dir_repo_functest = 'test_dir_repo_functest'
+ self.snapshot_file = 'test_snapshot_file'
+ self.cli_os = cli_os.CliOpenStack()
+
+ def test_ping_endpoint_default(self):
+ self.cli_os.os_auth_url = self.os_auth_url
+ self.cli_os.endpoint_ip = self.endpoint_ip
+ with mock.patch('functest.cli.commands.cli_os.os.system',
+ return_value=0):
+ self.assertEqual(self.cli_os.ping_endpoint(), 0)
+
+ @mock.patch('functest.cli.commands.cli_os.exit', side_effect=Exception)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_ping_endpoint_missing_auth_url(self, mock_click_echo,
+ mock_exit):
+ with self.assertRaises(Exception):
+ self.cli_os.os_auth_url = None
+ self.cli_os.ping_endpoint()
+ mock_click_echo.assert_called_once_with("Source the OpenStack "
+ "credentials first '. "
+ "$creds'")
+
+ @mock.patch('functest.cli.commands.cli_os.exit')
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_ping_endpoint_os_system_fails(self, mock_click_echo,
+ mock_exit):
+ self.cli_os.os_auth_url = self.os_auth_url
+ self.cli_os.endpoint_ip = self.endpoint_ip
+ with mock.patch('functest.cli.commands.cli_os.os.system',
+ return_value=1):
+ self.cli_os.ping_endpoint()
+ mock_click_echo.assert_called_once_with("Cannot talk to the "
+ "endpoint %s\n" %
+ self.endpoint_ip)
+ mock_exit.assert_called_once_with(0)
+
+ @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_fetch_credentials_default(self, mock_click_echo,
+ mock_os_path,
+ mock_ftutils_execute):
+ CONST.INSTALLER_TYPE = self.installer_type
+ CONST.INSTALLER_IP = self.installer_ip
+ cmd = ("%s/releng/utils/fetch_os_creds.sh -d %s -i %s -a %s"
+ % (CONST.dir_repos,
+ self.openstack_creds,
+ self.installer_type,
+ self.installer_ip))
+ self.cli_os.openstack_creds = self.openstack_creds
+ self.cli_os.fetch_credentials()
+ mock_click_echo.assert_called_once_with("Fetching credentials from "
+ "installer node '%s' with "
+ "IP=%s.." %
+ (self.installer_type,
+ self.installer_ip))
+ mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+ @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_fetch_credentials_missing_installer_type(self, mock_click_echo,
+ mock_os_path,
+ mock_ftutils_execute):
+ installer_type = None
+ installer_ip = self.installer_ip
+ CONST.INSTALLER_TYPE = installer_type
+ CONST.INSTALLER_IP = installer_ip
+ cmd = ("%s/releng/utils/fetch_os_creds.sh -d %s -i %s -a %s"
+ % (CONST.dir_repos,
+ self.openstack_creds,
+ installer_type,
+ installer_ip))
+ self.cli_os.openstack_creds = self.openstack_creds
+ self.cli_os.fetch_credentials()
+ mock_click_echo.assert_any_call("The environment variable "
+ "'INSTALLER_TYPE' is not"
+ "defined. Please export it")
+ mock_click_echo.assert_any_call("Fetching credentials from "
+ "installer node '%s' with "
+ "IP=%s.." %
+ (installer_type,
+ installer_ip))
+ mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+ @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_fetch_credentials_missing_installer_ip(self, mock_click_echo,
+ mock_os_path,
+ mock_ftutils_execute):
+ installer_type = self.installer_type
+ installer_ip = None
+ CONST.INSTALLER_TYPE = installer_type
+ CONST.INSTALLER_IP = installer_ip
+ cmd = ("%s/releng/utils/fetch_os_creds.sh -d %s -i %s -a %s"
+ % (CONST.dir_repos,
+ self.openstack_creds,
+ installer_type,
+ installer_ip))
+ self.cli_os.openstack_creds = self.openstack_creds
+ self.cli_os.fetch_credentials()
+ mock_click_echo.assert_any_call("The environment variable "
+ "'INSTALLER_IP' is not"
+ "defined. Please export it")
+ mock_click_echo.assert_any_call("Fetching credentials from "
+ "installer node '%s' with "
+ "IP=%s.." %
+ (installer_type,
+ installer_ip))
+ mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+ @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+ def test_check(self, mock_ftutils_execute):
+ with mock.patch.object(self.cli_os, 'ping_endpoint'):
+ CONST.dir_repo_functest = self.dir_repo_functest
+ cmd = CONST.dir_repo_functest + "/functest/ci/check_os.sh"
+ self.cli_os.check()
+ mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_snapshot_create(self, mock_click_echo, mock_os_path):
+ with mock.patch.object(self.cli_os, 'ping_endpoint'), \
+ mock.patch('functest.cli.commands.cli_os.os_snapshot.main') \
+ as mock_os_snapshot:
+ self.cli_os.snapshot_create()
+ mock_click_echo.assert_called_once_with("Generating Openstack "
+ "snapshot...")
+ self.assertTrue(mock_os_snapshot.called)
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_snapshot_create_overwrite(self, mock_click_echo, mock_os_path):
+ with mock.patch('__builtin__.raw_input', return_value="y") \
+ as mock_raw_input, \
+ mock.patch.object(self.cli_os, 'ping_endpoint'), \
+ mock.patch('functest.cli.commands.cli_os.os_snapshot.main') \
+ as mock_os_snapshot:
+ self.cli_os.snapshot_create()
+ mock_click_echo.assert_called_once_with("Generating Openstack "
+ "snapshot...")
+ mock_raw_input.assert_any_call("It seems there is already an "
+ "OpenStack snapshot. Do you want "
+ "to overwrite it with the current "
+ "OpenStack status? [y|n]\n")
+ self.assertTrue(mock_os_snapshot.called)
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_snapshot_show_missing_snap(self, mock_click_echo, mock_os_path):
+ self.cli_os.snapshot_show()
+ mock_click_echo.assert_called_once_with("There is no OpenStack "
+ "snapshot created. To create "
+ "one run the command "
+ "'functest openstack "
+ "snapshot-create'")
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_snapshot_show_default(self, mock_click_echo, mock_os_path):
+ with mock.patch('__builtin__.open', mock.mock_open(read_data='0')) \
+ as m:
+ self.cli_os.snapshot_file = self.snapshot_file
+ self.cli_os.snapshot_show()
+ m.assert_called_once_with(self.snapshot_file, 'r')
+ mock_click_echo.assert_called_once_with("\n0")
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_clean(self, mock_click_echo, mock_os_path):
+ with mock.patch.object(self.cli_os, 'ping_endpoint'), \
+ mock.patch('functest.cli.commands.cli_os.os_clean.main') \
+ as mock_os_clean:
+ self.cli_os.clean()
+ self.assertTrue(mock_os_clean.called)
+
+ @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_clean_missing_file(self, mock_click_echo, mock_os_path):
+ with mock.patch.object(self.cli_os, 'ping_endpoint'):
+ self.cli_os.clean()
+ mock_click_echo.assert_called_once_with("Not possible to clean "
+ "OpenStack without a "
+ "snapshot. This could "
+ "cause problems. "
+ "Run first the command "
+ "'functest openstack "
+ "snapshot-create'")
+
+ @mock.patch('functest.cli.commands.cli_os.click.echo')
+ def test_show_credentials(self, mock_click_echo):
+ key = 'OS_KEY'
+ value = 'OS_VALUE'
+ with mock.patch.dict(os.environ, {key: value}):
+ self.cli_os.show_credentials()
+ mock_click_echo.assert_called_once_with("{}={}".format(key, value))
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/commands/test_cli_testcase.py b/functest/tests/unit/cli/commands/test_cli_testcase.py
new file mode 100644
index 000000000..39c8139d7
--- /dev/null
+++ b/functest/tests/unit/cli/commands/test_cli_testcase.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+
+import logging
+import unittest
+
+import mock
+
+from functest.cli.commands import cli_testcase
+from functest.utils.constants import CONST
+
+
+class CliTestCasesTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.testname = 'testname'
+ with mock.patch('functest.cli.commands.cli_testcase.tb'):
+ self.cli_tests = cli_testcase.CliTestcase()
+
+ @mock.patch('functest.cli.commands.cli_testcase.vacation.main')
+ def test_run_vacation(self, mock_method):
+ self.cli_tests.run('vacation')
+ self.assertTrue(mock_method.called)
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+ def test_run_missing_env_file(self, mock_click_echo, mock_os):
+ self.cli_tests.run(self.testname)
+ mock_click_echo.assert_called_with("Functest environment is not ready."
+ " Run first 'functest env prepare'")
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_run_default(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-n -r ", self.testname))
+ self.cli_tests.run(self.testname, noclean=True, report=True)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_run_noclean_missing_report(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-n ", self.testname))
+ self.cli_tests.run(self.testname, noclean=True, report=False)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_run_report_missing_noclean(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-r ", self.testname))
+ self.cli_tests.run(self.testname, noclean=False, report=True)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+ def test_run_missing_noclean_report(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "", self.testname))
+ self.cli_tests.run(self.testname, noclean=False, report=False)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+ def test_list(self, mock_click_echo):
+ with mock.patch.object(self.cli_tests.tiers, 'get_tiers',
+ return_value=[]):
+ self.cli_tests.list()
+ mock_click_echo.assert_called_with("")
+
+ @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+ def test_show_default_desc_none(self, mock_click_echo):
+ with mock.patch.object(self.cli_tests.tiers, 'get_test',
+ return_value=None):
+ self.cli_tests.show(self.testname)
+ mock_click_echo.assert_any_call("The test case '%s' "
+ "does not exist or is"
+ " not supported."
+ % self.testname)
+
+ @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+ def test_show_default(self, mock_click_echo):
+ mock_obj = mock.Mock()
+ with mock.patch.object(self.cli_tests.tiers, 'get_test',
+ return_value=mock_obj):
+ self.cli_tests.show(self.testname)
+ mock_click_echo.assert_called_with(mock_obj)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/commands/test_cli_tier.py b/functest/tests/unit/cli/commands/test_cli_tier.py
new file mode 100644
index 000000000..802359f16
--- /dev/null
+++ b/functest/tests/unit/cli/commands/test_cli_tier.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+
+import logging
+import unittest
+
+import mock
+
+from functest.cli.commands import cli_tier
+from functest.utils.constants import CONST
+
+
+class CliTierTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.tiername = 'tiername'
+ self.testnames = 'testnames'
+ with mock.patch('functest.cli.commands.cli_tier.tb'):
+ self.cli_tier = cli_tier.CliTier()
+
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_list(self, mock_click_echo):
+ with mock.patch.object(self.cli_tier.tiers, 'get_tiers',
+ return_value=[]):
+ self.cli_tier.list()
+ mock_click_echo.assert_called_with("")
+
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_show_default(self, mock_click_echo):
+ with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+ return_value=self.tiername):
+ self.cli_tier.show(self.tiername)
+ mock_click_echo.assert_called_with(self.tiername)
+
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_show_missing_tier(self, mock_click_echo):
+ with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+ return_value=None), \
+ mock.patch.object(self.cli_tier.tiers, 'get_tier_names',
+ return_value='tiernames'):
+ self.cli_tier.show(self.tiername)
+ mock_click_echo.assert_called_with("The tier with name '%s' does "
+ "not exist. Available tiers are"
+ ":\n %s\n" % (self.tiername,
+ 'tiernames'))
+
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_gettests_default(self, mock_click_echo):
+ mock_obj = mock.Mock()
+ attrs = {'get_test_names.return_value': self.testnames}
+ mock_obj.configure_mock(**attrs)
+
+ with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+ return_value=mock_obj):
+ self.cli_tier.gettests(self.tiername)
+ mock_click_echo.assert_called_with("Test cases in tier "
+ "'%s':\n %s\n" % (self.tiername,
+ self.testnames
+ ))
+
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_gettests_missing_tier(self, mock_click_echo):
+ with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+ return_value=None), \
+ mock.patch.object(self.cli_tier.tiers, 'get_tier_names',
+ return_value='tiernames'):
+ self.cli_tier.gettests(self.tiername)
+ mock_click_echo.assert_called_with("The tier with name '%s' does "
+ "not exist. Available tiers are"
+ ":\n %s\n" % (self.tiername,
+ 'tiernames'))
+
+ @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+ return_value=False)
+ @mock.patch('functest.cli.commands.cli_tier.click.echo')
+ def test_run_missing_env_file(self, mock_click_echo, mock_os):
+ self.cli_tier.run(self.tiername)
+ mock_click_echo.assert_called_with("Functest environment is not ready."
+ " Run first 'functest env prepare'")
+
+ @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+ def test_run_default(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-n -r ",
+ self.tiername))
+ self.cli_tier.run(self.tiername, noclean=True, report=True)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+ def test_run_report_missing_noclean(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-r ",
+ self.tiername))
+ self.cli_tier.run(self.tiername, noclean=False, report=True)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+ def test_run_noclean_missing_report(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "-n ",
+ self.tiername))
+ self.cli_tier.run(self.tiername, noclean=True, report=False)
+ mock_ft_utils.assert_called_with(cmd)
+
+ @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+ return_value=True)
+ @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+ def test_run_missing_noclean_report(self, mock_ft_utils, mock_os):
+ cmd = ("python %s/functest/ci/run_tests.py "
+ "%s -t %s" % (CONST.dir_repo_functest, "",
+ self.tiername))
+ self.cli_tier.run(self.tiername, noclean=False, report=False)
+ mock_ft_utils.assert_called_with(cmd)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/test_cli_base.py b/functest/tests/unit/cli/test_cli_base.py
new file mode 100644
index 000000000..fe065c2aa
--- /dev/null
+++ b/functest/tests/unit/cli/test_cli_base.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2016 Orange and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import logging
+import unittest
+
+import mock
+from click.testing import CliRunner
+
+with mock.patch('functest.cli.commands.cli_testcase.CliTestcase.__init__',
+ mock.Mock(return_value=None)), \
+ mock.patch('functest.cli.commands.cli_tier.CliTier.__init__',
+ mock.Mock(return_value=None)):
+ from functest.cli import cli_base
+
+
+class CliBaseTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.runner = CliRunner()
+ self._openstack = cli_base._openstack
+ self._env = cli_base._env
+ self._testcase = cli_base._testcase
+ self._tier = cli_base._tier
+
+ def test_os_check(self):
+ with mock.patch.object(self._openstack, 'check') as mock_method:
+ result = self.runner.invoke(cli_base.os_check)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_os_snapshot_create(self):
+ with mock.patch.object(self._openstack, 'snapshot_create') \
+ as mock_method:
+ result = self.runner.invoke(cli_base.os_snapshot_create)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_os_snapshot_show(self):
+ with mock.patch.object(self._openstack, 'snapshot_show') \
+ as mock_method:
+ result = self.runner.invoke(cli_base.os_snapshot_show)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_os_clean(self):
+ with mock.patch.object(self._openstack, 'clean') as mock_method:
+ result = self.runner.invoke(cli_base.os_clean)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_os_show_credentials(self):
+ with mock.patch.object(self._openstack, 'show_credentials') \
+ as mock_method:
+ result = self.runner.invoke(cli_base.os_show_credentials)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_os_fetch_rc(self):
+ with mock.patch.object(self._openstack, 'fetch_credentials') \
+ as mock_method:
+ result = self.runner.invoke(cli_base.os_fetch_rc)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_env_prepare(self):
+ with mock.patch.object(self._env, 'prepare') as mock_method:
+ result = self.runner.invoke(cli_base.env_prepare)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_env_show(self):
+ with mock.patch.object(self._env, 'show') as mock_method:
+ result = self.runner.invoke(cli_base.env_show)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_env_status(self):
+ with mock.patch.object(self._env, 'status') as mock_method:
+ result = self.runner.invoke(cli_base.env_status)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_testcase_list(self):
+ with mock.patch.object(self._testcase, 'list') as mock_method:
+ result = self.runner.invoke(cli_base.testcase_list)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_testcase_show(self):
+ with mock.patch.object(self._testcase, 'show') as mock_method:
+ result = self.runner.invoke(cli_base.testcase_show, ['testname'])
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_testcase_run(self):
+ with mock.patch.object(self._testcase, 'run') as mock_method:
+ result = self.runner.invoke(cli_base.testcase_run,
+ ['testname', '--noclean'])
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_tier_list(self):
+ with mock.patch.object(self._tier, 'list') as mock_method:
+ result = self.runner.invoke(cli_base.tier_list)
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_tier_show(self):
+ with mock.patch.object(self._tier, 'show') as mock_method:
+ result = self.runner.invoke(cli_base.tier_show, ['tiername'])
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_tier_gettests(self):
+ with mock.patch.object(self._tier, 'gettests') as mock_method:
+ result = self.runner.invoke(cli_base.tier_gettests, ['tiername'])
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+ def test_tier_run(self):
+ with mock.patch.object(self._tier, 'run') as mock_method:
+ result = self.runner.invoke(cli_base.tier_run,
+ ['tiername', '--noclean'])
+ self.assertEqual(result.exit_code, 0)
+ self.assertTrue(mock_method.called)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/core/test_testcase_base.py b/functest/tests/unit/core/test_testcase_base.py
index fe7b0d054..b7c81d87c 100644
--- a/functest/tests/unit/core/test_testcase_base.py
+++ b/functest/tests/unit/core/test_testcase_base.py
@@ -11,7 +11,7 @@ import logging
import mock
import unittest
-import functest.core.testcase_base as testcase_base
+from functest.core import testcase_base
class TestcaseBaseTesting(unittest.TestCase):
@@ -24,7 +24,7 @@ class TestcaseBaseTesting(unittest.TestCase):
self.test.case_name = "base"
self.test.start_time = "1"
self.test.stop_time = "2"
- self.test.criteria = "100"
+ self.test.criteria = "PASS"
self.test.details = {"Hello": "World"}
def test_run_unimplemented(self):
@@ -82,6 +82,21 @@ class TestcaseBaseTesting(unittest.TestCase):
self.test.project, self.test.case_name, self.test.start_time,
self.test.stop_time, self.test.criteria, self.test.details)
+ def test_check_criteria_missing(self):
+ self.test.criteria = None
+ self.assertEqual(self.test.check_criteria(),
+ testcase_base.TestcaseBase.EX_TESTCASE_FAILED)
+
+ def test_check_criteria_failed(self):
+ self.test.criteria = 'FAILED'
+ self.assertEqual(self.test.check_criteria(),
+ testcase_base.TestcaseBase.EX_TESTCASE_FAILED)
+
+ def test_check_criteria_pass(self):
+ self.test.criteria = 'PASS'
+ self.assertEqual(self.test.check_criteria(),
+ testcase_base.TestcaseBase.EX_OK)
+
if __name__ == "__main__":
unittest.main(verbosity=2)
diff --git a/functest/tests/unit/odl/test_odl.py b/functest/tests/unit/odl/test_odl.py
index ef18016bf..d8c7f84ec 100644
--- a/functest/tests/unit/odl/test_odl.py
+++ b/functest/tests/unit/odl/test_odl.py
@@ -13,11 +13,12 @@ import mock
import os
import unittest
+from keystoneauth1.exceptions import auth_plugins
from robot.errors import RobotError
+from robot.result import testcase
-import functest.core.testcase_base as testcase_base
+from functest.core import testcase_base
from functest.opnfv_tests.sdn.odl import odl
-from functest.utils import functest_constants as ft_constants
class ODLTesting(unittest.TestCase):
@@ -36,11 +37,41 @@ class ODLTesting(unittest.TestCase):
_odl_password = "admin"
def setUp(self):
- ft_constants.OS_USERNAME = self._os_username
- ft_constants.OS_PASSWORD = self._os_password
- ft_constants.OS_TENANT_NAME = self._os_tenantname
+ for var in ("INSTALLER_TYPE", "SDN_CONTROLLER", "SDN_CONTROLLER_IP"):
+ if var in os.environ:
+ del os.environ[var]
+ os.environ["OS_USERNAME"] = self._os_username
+ os.environ["OS_PASSWORD"] = self._os_password
+ os.environ["OS_TENANT_NAME"] = self._os_tenantname
self.test = odl.ODLTests()
+ def test_empty_visitor(self):
+ visitor = odl.ODLResultVisitor()
+ self.assertFalse(visitor.get_data())
+
+ def test_visitor(self):
+ visitor = odl.ODLResultVisitor()
+ data = {'name': 'foo',
+ 'parent': 'bar',
+ 'status': 'PASS',
+ 'starttime': "20161216 16:00:00.000",
+ 'endtime': "20161216 16:00:01.000",
+ 'elapsedtime': 1000,
+ 'text': 'Hello, World!',
+ 'critical': True}
+ test = testcase.TestCase(name=data['name'],
+ status=data['status'],
+ message=data['text'],
+ starttime=data['starttime'],
+ endtime=data['endtime'])
+ test.parent = mock.Mock()
+ config = {'name': data['parent'],
+ 'criticality.test_is_critical.return_value': data[
+ 'critical']}
+ test.parent.configure_mock(**config)
+ visitor.visit_test(test)
+ self.assertEqual(visitor.get_data(), [data])
+
@mock.patch('fileinput.input', side_effect=Exception())
def test_set_robotframework_vars_failed(self, *args):
self.assertFalse(self.test.set_robotframework_vars())
@@ -59,14 +90,6 @@ class ODLTesting(unittest.TestCase):
else:
return None
- @classmethod
- def _get_fake_keystone_client(cls):
- kclient = mock.Mock()
- kclient.service_catalog = mock.Mock()
- kclient.service_catalog.url_for = mock.Mock(
- side_effect=cls._fake_url_for)
- return kclient
-
def _get_main_kwargs(self, key=None):
kwargs = {'odlusername': self._odl_username,
'odlpassword': self._odl_password,
@@ -85,9 +108,9 @@ class ODLTesting(unittest.TestCase):
def _test_main(self, status, *args):
kwargs = self._get_main_kwargs()
self.assertEqual(self.test.main(**kwargs), status)
- odl_res_dir = odl.ODLTests.res_dir
if len(args) > 0:
- args[0].assert_called_once_with(odl_res_dir)
+ args[0].assert_called_once_with(
+ odl.ODLTests.res_dir)
if len(args) > 1:
variable = ['KEYSTONE:{}'.format(self._keystone_ip),
'NEUTRON:{}'.format(self._neutron_ip),
@@ -97,18 +120,17 @@ class ODLTesting(unittest.TestCase):
'ODL_SYSTEM_IP:{}'.format(self._sdn_controller_ip),
'PORT:{}'.format(self._odl_webport),
'RESTCONFPORT:{}'.format(self._odl_restconfport)]
- output_file = os.path.join(odl_res_dir, 'output.xml')
args[1].assert_called_once_with(
odl.ODLTests.basic_suite_dir,
odl.ODLTests.neutron_suite_dir,
log='NONE',
- output=output_file,
+ output=os.path.join(odl.ODLTests.res_dir, 'output.xml'),
report='NONE',
stdout=mock.ANY,
variable=variable)
if len(args) > 2:
- stdout_file = os.path.join(odl_res_dir, 'stdout.txt')
- args[2].assert_called_with(stdout_file)
+ args[2].assert_called_with(
+ os.path.join(odl.ODLTests.res_dir, 'stdout.txt'))
def _test_main_missing_keyword(self, key):
kwargs = self._get_main_kwargs(key)
@@ -200,8 +222,7 @@ class ODLTesting(unittest.TestCase):
def test_main(self, *args):
with mock.patch.object(self.test, 'set_robotframework_vars',
return_value=True), \
- mock.patch.object(self.test, 'parse_results',
- return_value="PASS"):
+ mock.patch.object(self.test, 'parse_results'):
self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
@mock.patch('os.remove')
@@ -210,8 +231,7 @@ 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(self.test, 'parse_results',
- return_value="PASS"):
+ mock.patch.object(self.test, 'parse_results'):
self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
@mock.patch('os.remove')
@@ -220,8 +240,7 @@ 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(self.test, 'parse_results',
- return_value="PASS"):
+ mock.patch.object(self.test, 'parse_results'):
self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
@mock.patch('os.remove', side_effect=OSError)
@@ -230,25 +249,20 @@ 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(self.test, 'parse_results',
- return_value="PASS"):
+ mock.patch.object(self.test, 'parse_results'):
self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
def _test_run_missing_env_var(self, var):
- if var == 'OS_USERNAME':
- ft_constants.OS_USERNAME = None
- elif var == 'OS_PASSWORD':
- ft_constants.OS_PASSWORD = None
- elif var == 'OS_TENANT_NAME':
- ft_constants.OS_TENANT_NAME = None
-
- self.assertEqual(self.test.run(),
- testcase_base.TestcaseBase.EX_RUN_ERROR)
+ with mock.patch('functest.utils.openstack_utils.get_endpoint',
+ side_effect=self._fake_url_for):
+ del os.environ[var]
+ self.assertEqual(self.test.run(),
+ 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"):
- with mock.patch('functest.utils.openstack_utils.get_keystone_client',
- return_value=self._get_fake_keystone_client()):
+ with mock.patch('functest.utils.openstack_utils.get_endpoint',
+ side_effect=self._fake_url_for):
if exception:
self.test.main = mock.Mock(side_effect=exception)
else:
@@ -262,6 +276,12 @@ class ODLTesting(unittest.TestCase):
ospassword=self._os_password, ostenantname=self._os_tenantname,
osusername=self._os_username)
+ def test_run_exception(self):
+ with mock.patch('functest.utils.openstack_utils.get_endpoint',
+ side_effect=auth_plugins.MissingAuthPlugin()):
+ self.assertEqual(self.test.run(),
+ testcase_base.TestcaseBase.EX_RUN_ERROR)
+
def test_run_missing_os_username(self):
self._test_run_missing_env_var("OS_USERNAME")
@@ -272,72 +292,64 @@ class ODLTesting(unittest.TestCase):
self._test_run_missing_env_var("OS_TENANT_NAME")
def test_run_main_false(self):
- ft_constants.CI_INSTALLER_TYPE = None
- ft_constants.SDN_CONTROLLER_IP = self._sdn_controller_ip
+ os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
self._test_run(testcase_base.TestcaseBase.EX_RUN_ERROR,
odlip=self._sdn_controller_ip,
odlwebport=self._odl_webport)
def test_run_main_exception(self):
- ft_constants.CI_INSTALLER_TYPE = None
- ft_constants.SDN_CONTROLLER_IP = self._sdn_controller_ip
with self.assertRaises(Exception):
+ os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
self._test_run(status=testcase_base.TestcaseBase.EX_RUN_ERROR,
exception=Exception(),
odlip=self._sdn_controller_ip,
odlwebport=self._odl_webport)
def test_run_missing_sdn_controller_ip(self):
- with mock.patch('functest.utils.openstack_utils.get_keystone_client',
- return_value=self._get_fake_keystone_client()):
- ft_constants.CI_INSTALLER_TYPE = None
- ft_constants.SDN_CONTROLLER_IP = None
+ with mock.patch('functest.utils.openstack_utils.get_endpoint',
+ side_effect=self._fake_url_for):
self.assertEqual(self.test.run(),
testcase_base.TestcaseBase.EX_RUN_ERROR)
def test_run_without_installer_type(self):
- ft_constants.SDN_CONTROLLER_IP = self._sdn_controller_ip
- ft_constants.CI_INSTALLER_TYPE = None
+ os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
self._test_run(testcase_base.TestcaseBase.EX_OK,
odlip=self._sdn_controller_ip,
odlwebport=self._odl_webport)
def test_run_fuel(self):
- ft_constants.CI_INSTALLER_TYPE = "fuel"
+ os.environ["INSTALLER_TYPE"] = "fuel"
self._test_run(testcase_base.TestcaseBase.EX_OK,
odlip=self._neutron_ip, odlwebport='8282')
def test_run_apex_missing_sdn_controller_ip(self):
- with mock.patch('functest.utils.openstack_utils.get_keystone_client',
- return_value=self._get_fake_keystone_client()):
- ft_constants.CI_INSTALLER_TYPE = "apex"
- ft_constants.SDN_CONTROLLER_IP = None
+ with mock.patch('functest.utils.openstack_utils.get_endpoint',
+ side_effect=self._fake_url_for):
+ os.environ["INSTALLER_TYPE"] = "apex"
self.assertEqual(self.test.run(),
testcase_base.TestcaseBase.EX_RUN_ERROR)
def test_run_apex(self):
- ft_constants.SDN_CONTROLLER_IP = self._sdn_controller_ip
- ft_constants.CI_INSTALLER_TYPE = "apex"
+ 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')
def test_run_joid_missing_sdn_controller(self):
- with mock.patch('functest.utils.openstack_utils.get_keystone_client',
- return_value=self._get_fake_keystone_client()):
- ft_constants.CI_INSTALLER_TYPE = "joid"
- ft_constants.SDN_CONTROLLER = None
+ with mock.patch('functest.utils.openstack_utils.get_endpoint',
+ side_effect=self._fake_url_for):
+ os.environ["INSTALLER_TYPE"] = "joid"
self.assertEqual(self.test.run(),
testcase_base.TestcaseBase.EX_RUN_ERROR)
def test_run_joid(self):
- ft_constants.SDN_CONTROLLER = self._sdn_controller_ip
- ft_constants.CI_INSTALLER_TYPE = "joid"
+ os.environ["SDN_CONTROLLER"] = self._sdn_controller_ip
+ os.environ["INSTALLER_TYPE"] = "joid"
self._test_run(testcase_base.TestcaseBase.EX_OK,
- odlip=self._sdn_controller_ip,
- odlwebport=self._odl_webport)
+ odlip=self._sdn_controller_ip, odlwebport='8080')
def test_run_compass(self, *args):
- ft_constants.CI_INSTALLER_TYPE = "compass"
+ os.environ["INSTALLER_TYPE"] = "compass"
self._test_run(testcase_base.TestcaseBase.EX_OK,
odlip=self._neutron_ip, odlwebport='8181')
diff --git a/functest/tests/unit/test_utils.py b/functest/tests/unit/test_utils.py
new file mode 100644
index 000000000..e171db022
--- /dev/null
+++ b/functest/tests/unit/test_utils.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import re
+
+
+class RegexMatch(str):
+ def __eq__(self, other):
+ match = re.search(self, other)
+ if match:
+ return True
+ return False
+
+
+class SubstrMatch(str):
+ def __eq__(self, other):
+ if self in other:
+ return True
+ return False
diff --git a/functest/tests/unit/utils/test_functest_utils.py b/functest/tests/unit/utils/test_functest_utils.py
new file mode 100644
index 000000000..ce9086a7a
--- /dev/null
+++ b/functest/tests/unit/utils/test_functest_utils.py
@@ -0,0 +1,599 @@
+#!/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
+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_utils.py b/functest/tests/unit/utils/test_utils.py
deleted file mode 100644
index 8b6c5e1b9..000000000
--- a/functest/tests/unit/utils/test_utils.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 Orange and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-
-import logging
-import mock
-import unittest
-import urllib2
-
-from functest.utils import functest_utils
-
-
-class FunctestUtilsTesting(unittest.TestCase):
-
- logging.disable(logging.CRITICAL)
-
- def setUp(self):
- self.url = 'http://www.opnfv.org/'
- self.timeout = 5
-
- @mock.patch('urllib2.urlopen',
- side_effect=urllib2.URLError('no host given'))
- def test_check_internet_connectivity_failed(self, mock_method):
- self.assertFalse(functest_utils.check_internet_connectivity())
- mock_method.assert_called_once_with(self.url, timeout=self.timeout)
-
- @mock.patch('urllib2.urlopen')
- def test_check_internet_connectivity_default(self, mock_method):
- self.assertTrue(functest_utils.check_internet_connectivity())
- mock_method.assert_called_once_with(self.url, timeout=self.timeout)
-
- @mock.patch('urllib2.urlopen')
- def test_check_internet_connectivity_debian(self, mock_method):
- self.url = "https://www.debian.org/"
- self.assertTrue(functest_utils.check_internet_connectivity(self.url))
- mock_method.assert_called_once_with(self.url, timeout=self.timeout)
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/functest/utils/config.py b/functest/utils/config.py
new file mode 100644
index 000000000..84166c1d3
--- /dev/null
+++ b/functest/utils/config.py
@@ -0,0 +1,35 @@
+import os
+
+import yaml
+
+
+class Config(object):
+ def __init__(self):
+ if 'CONFIG_FUNCTEST_YAML' not in os.environ:
+ raise Exception('CONFIG_FUNCTEST_YAML not configed')
+ self.config_functest = os.environ['CONFIG_FUNCTEST_YAML']
+ try:
+ with open(self.config_functest) as f:
+ self.functest_yaml = yaml.safe_load(f)
+ 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):
+ for param_n, param_v in left_parametes.iteritems():
+ 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)
+
+ def _get_attr_further(self, attr_now, next):
+ return attr_now if next == 'general' else (
+ '{}_{}'.format(attr_now, next) if attr_now else next)
+
+ def _set_others(self):
+ self.env_active = os.path.join(self.dir_functest_conf, "env_active")
+
+
+CONF = Config()
diff --git a/functest/utils/constants.py b/functest/utils/constants.py
new file mode 100644
index 000000000..2e8eb3f44
--- /dev/null
+++ b/functest/utils/constants.py
@@ -0,0 +1,20 @@
+import config
+import env
+
+
+class Constants(object):
+ def __init__(self):
+ for attr_n, attr_v in config.CONF.__dict__.iteritems():
+ self.__setattr__(attr_n, attr_v)
+ for env_n, env_v in env.ENV.__dict__.iteritems():
+ self.__setattr__(env_n, env_v)
+
+
+CONST = Constants()
+
+if __name__ == '__main__':
+ print CONST.__dict__
+ print CONST.NODE_NAME
+ print CONST.vIMS_clearwater_blueprint_url
+ print CONST.vIMS_clearwater_blueprint_file_name
+ print CONST.vIMS_clearwater_blueprint_name
diff --git a/functest/utils/env.py b/functest/utils/env.py
new file mode 100644
index 000000000..fa5245fb6
--- /dev/null
+++ b/functest/utils/env.py
@@ -0,0 +1,41 @@
+import os
+import re
+
+default_envs = {
+ 'NODE_NAME': 'unknown_pod',
+ 'CI_DEBUG': 'true',
+ 'DEPLOY_SCENARIO': 'os-nosdn-nofeature-noha',
+ 'DEPLOY_TYPE': 'virt',
+ 'INSTALLER_TYPE': None,
+ 'INSTALLER_IP': None,
+ 'BUILD_TAG': None,
+ 'OS_ENDPOINT_TYPE': None,
+ 'OS_AUTH_URL': None
+}
+
+
+class Environment(object):
+
+ def __init__(self):
+ for k, v in os.environ.iteritems():
+ self.__setattr__(k, v)
+ for k, v in default_envs.iteritems():
+ if k not in os.environ:
+ self.__setattr__(k, v)
+ self._set_ci_run()
+ self._set_ci_loop()
+
+ def _set_ci_run(self):
+ if self.BUILD_TAG:
+ self.IS_CI_RUN = True
+ else:
+ self.IS_CI_RUN = False
+
+ def _set_ci_loop(self):
+ if self.BUILD_TAG and re.search("daily", self.BUILD_TAG):
+ self.CI_LOOP = "daily"
+ else:
+ self.CI_LOOP = "weekly"
+
+
+ENV = Environment()
diff --git a/functest/utils/functest_constants.py b/functest/utils/functest_constants.py
index 2664ace1f..ac9d77c87 100644
--- a/functest/utils/functest_constants.py
+++ b/functest/utils/functest_constants.py
@@ -7,8 +7,9 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
import os
-import functest.utils.functest_utils as ft_utils
+
import functest.utils.functest_logger as ft_logger
+import functest.utils.functest_utils as ft_utils
logger = ft_logger.Logger("functest_constants").getLogger()
@@ -60,25 +61,25 @@ def get_value(functest_config_key, env_variable):
return constant
-HOME = get_value('general.directories.dir_home', 'HOME')
-REPOS_DIR = get_value('general.directories.dir_repos', 'REPOS_DIR')
-FUNCTEST_BASE_DIR = get_value('general.directories.dir_functest',
+HOME = get_value('general.dir.home', 'HOME')
+REPOS_DIR = get_value('general.dir.repos', 'REPOS_DIR')
+FUNCTEST_BASE_DIR = get_value('general.dir.functest',
'FUNCTEST_BASE_DIR')
-FUNCTEST_REPO_DIR = get_value('general.directories.dir_repo_functest',
+FUNCTEST_REPO_DIR = get_value('general.dir.repo_functest',
'FUNCTEST_REPO_DIR')
-FUNCTEST_TEST_DIR = get_value('general.directories.dir_functest_test',
+FUNCTEST_TEST_DIR = get_value('general.dir.functest_test',
'FUNCTEST_TEST_DIR')
-FUNCTEST_CONF_DIR = get_value('general.directories.dir_functest_conf',
+FUNCTEST_CONF_DIR = get_value('general.dir.functest_conf',
'FUNCTEST_CONF_DIR')
-FUNCTEST_DATA_DIR = get_value('general.directories.dir_functest_data',
+FUNCTEST_DATA_DIR = get_value('general.dir.functest_data',
'FUNCTEST_DATA_DIR')
-FUNCTEST_RESULTS_DIR = get_value('general.directories.dir_results',
+FUNCTEST_RESULTS_DIR = get_value('general.dir.results',
'FUNCTEST_RESULTS_DIR')
FUNCTEST_TESTCASES_YAML = get_value('general.functest.testcases_yaml',
'FUNCTEST_TESTCASES_YAML')
RALLY_DEPLOYMENT_NAME = get_value('rally.deployment_name',
'RALLY_DEPLOYMENT_NAME')
-TEMPEST_REPO_DIR = get_value('general.directories.dir_repo_tempest',
+TEMPEST_REPO_DIR = get_value('general.dir.repo_tempest',
'TEMPEST_REPO_DIR')
ENV_FILE = os.path.join(FUNCTEST_CONF_DIR, "env_active")
@@ -87,22 +88,22 @@ OPENSTACK_CREDS = get_value('general.openstack.creds', 'creds')
OPENSTACK_SNAPSHOT_FILE = get_value('general.openstack.snapshot_file',
'OPENSTACK_SNAPSHOT_FILE')
-DOMINO_REPO_DIR = get_value('general.directories.dir_repo_domino',
+DOMINO_REPO_DIR = get_value('general.dir.repo_domino',
'DOMINO_REPO_DIR')
-SDNVPN_REPO_DIR = get_value('general.directories.dir_repo_sdnvpn',
+SDNVPN_REPO_DIR = get_value('general.dir.repo_sdnvpn',
'SDNVPN_REPO_DIR')
-SFC_REPO_DIR = get_value('general.directories.dir_repo_sfc',
+SFC_REPO_DIR = get_value('general.dir.repo_sfc',
'SFC_REPO_DIR')
ONOS_SFC_IMAGE_NAME = get_value('onos_sfc.image_name',
'ONOS_SFC_IMAGE_NAME')
ONOS_SFC_IMAGE_FILENAME = get_value('onos_sfc.image_file_name',
'ONOS_SFC_IMAGE_FILENAME')
-ONOS_SFC_RELATIVE_PATH = get_value('general.directories.dir_onos_sfc',
+ONOS_SFC_RELATIVE_PATH = get_value('general.dir.dir_onos_sfc',
'ONOS_SFC_RELATIVE_PATH')
ONOS_SFC_IMAGE_BASE_URL = get_value('onos_sfc.image_base_url',
'ONOS_SFC_IMAGE_BASE_URL')
-RALLY_RELATIVE_PATH = get_value('general.directories.dir_rally',
+RALLY_RELATIVE_PATH = get_value('general.dir.rally',
'RALLY_RELATIVE_PATH')
RALLY_PRIVATE_NET_NAME = get_value('rally.network_name',
'RALLY_PRIVATE_NET_NAME')
@@ -111,7 +112,7 @@ RALLY_PRIVATE_SUBNET_NAME = get_value('rally.subnet_name',
RALLY_PRIVATE_SUBNET_CIDR = get_value('rally.subnet_cidr',
'RALLY_PRIVATE_SUBNET_CIDR')
RALLY_ROUTER_NAME = get_value('rally.router_name', 'RALLY_ROUTER_NAME')
-RALLY_INSTALLATION_DIR = get_value('general.directories.dir_rally_inst',
+RALLY_INSTALLATION_DIR = get_value('general.dir.rally_inst',
'RALLY_INSTALLATION_DIR')
GLANCE_IMAGE_NAME = get_value('general.openstack.image_name',
'GLANCE_IMAGE_NAME')
@@ -149,24 +150,24 @@ TEMPEST_USE_CUSTOM_IMAGES = get_value('tempest.use_custom_images',
'TEMPEST_USE_CUSTOM_IMAGES')
TEMPEST_USE_CUSTOM_FLAVORS = get_value('tempest.use_custom_flavors',
'TEMPEST_USE_CUSTOM_FLAVORS')
-TEMPEST_TEST_LIST_DIR = get_value('general.directories.dir_tempest_cases',
+TEMPEST_TEST_LIST_DIR = get_value('general.dir.tempest_cases',
'TEMPEST_TEST_LIST_DIR')
NAME_VM_1 = get_value('vping.vm_name_1', 'NAME_VM_1')
NAME_VM_2 = get_value('vping.vm_name_2', 'NAME_VM_2')
PING_TIMEOUT = get_value('vping.ping_timeout', 'PING_TIMEOUT')
VPING__IMAGE_NAME = get_value('vping.image_name', 'VPING__IMAGE_NAME')
VPING_VM_FLAVOR = get_value('vping.vm_flavor', 'VPING_VM_FLAVOR')
-VPING_PRIVATE_NET_NAME = get_value('vping.vping_private_net_name',
+VPING_PRIVATE_NET_NAME = get_value('vping.private_net_name',
'VPING_PRIVATE_NET_NAME')
-VPING_PRIVATE_SUBNET_NAME = get_value('vping.vping_private_subnet_name',
+VPING_PRIVATE_SUBNET_NAME = get_value('vping.private_subnet_name',
'VPING_PRIVATE_SUBNET_NAME')
-VPING_PRIVATE_SUBNET_CIDR = get_value('vping.vping_private_subnet_cidr',
+VPING_PRIVATE_SUBNET_CIDR = get_value('vping.private_subnet_cidr',
'VPING_PRIVATE_SUBNET_CIDR')
-VPING_ROUTER_NAME = get_value('vping.vping_router_name',
+VPING_ROUTER_NAME = get_value('vping.router_name',
'VPING_ROUTER_NAME')
-VPING_SECGROUP_NAME = get_value('vping.vping_sg_name',
+VPING_SECGROUP_NAME = get_value('vping.sg_name',
'VPING_SECGROUP_NAME')
-VPING_SECGROUP_DESCR = get_value('vping.vping_sg_descr',
+VPING_SECGROUP_DESCR = get_value('vping.sg_desc',
'VPING_SECGROUP_DESCR')
ONOSBENCH_USERNAME = get_value('ONOS.general.onosbench_username',
'ONOSBENCH_USERNAME')
@@ -192,7 +193,7 @@ ONOS_INSTALLER_MASTER_USERNAME = get_value(
ONOS_INSTALLER_MASTER_PASSWORD = get_value(
'ONOS.environment.installer_master_password',
'ONOS_INSTALLER_MASTER_PASSWORD')
-PROMISE_REPO_DIR = get_value('general.directories.dir_repo_promise',
+PROMISE_REPO_DIR = get_value('general.dir.dir_repo_promise',
'PROMISE_REPO_DIR')
PROMISE_TENANT_NAME = get_value('promise.tenant_name',
'PROMISE_TENANT_NAME')
@@ -217,32 +218,32 @@ 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 = get_value('general.dir.dir_vIMS_data',
'VIMS_DATA_DIR')
-VIMS_TEST_DIR = get_value('general.directories.dir_repo_vims_test',
+VIMS_TEST_DIR = get_value('general.dir.dir_repo_vims_test',
'VIMS_TEST_DIR')
VIMS_TENANT_NAME = get_value('vIMS.general.tenant_name',
'VIMS_TENANT_NAME')
@@ -260,5 +261,5 @@ CW_DEPLOYMENT_NAME = get_value('vIMS.clearwater.deployment-name',
CW_INPUTS = get_value('vIMS.clearwater.inputs', 'CW_INPUTS')
CW_REQUIERMENTS = get_value('vIMS.clearwater.requierments',
'CW_REQUIERMENTS')
-PARSER_REPO_DIR = get_value('general.directories.dir_repo_parser',
+PARSER_REPO_DIR = get_value('general.dir.repo_parser',
'PARSER_REPO_DIR')
diff --git a/functest/utils/functest_utils.py b/functest/utils/functest_utils.py
index b1e4d3cdb..1879e6943 100644
--- a/functest/utils/functest_utils.py
+++ b/functest/utils/functest_utils.py
@@ -7,12 +7,14 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
#
+import functools
import json
import os
import re
import shutil
import subprocess
import sys
+import time
import urllib2
from datetime import datetime as dt
@@ -21,9 +23,6 @@ import requests
import yaml
from git import Repo
-import time
-import functools
-
import functest.utils.functest_logger as ft_logger
logger = ft_logger.Logger("functest_utils").getLogger()
@@ -321,26 +320,6 @@ def execute_command(cmd, info=False, error_msg="",
return returncode
-def get_deployment_dir():
- """
- Returns current Rally deployment directory
- """
- deployment_name = get_functest_config('rally.deployment_name')
- rally_dir = get_functest_config('general.directories.dir_rally_inst')
- cmd = ("rally deployment list | awk '/" + deployment_name +
- "/ {print $2}'")
- p = subprocess.Popen(cmd, shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- deployment_uuid = p.stdout.readline().rstrip()
- if deployment_uuid == "":
- logger.error("Rally deployment not found.")
- exit(-1)
- deployment_dir = (rally_dir + "/tempest/for-deployment-" +
- deployment_uuid)
- return deployment_dir
-
-
def get_dict_by_test(testname):
with open(get_testcases_file_dir()) as f:
testcases_yaml = yaml.safe_load(f)
diff --git a/functest/utils/openstack_clean.py b/functest/utils/openstack_clean.py
index 949eee90f..15a8f33d5 100755
--- a/functest/utils/openstack_clean.py
+++ b/functest/utils/openstack_clean.py
@@ -9,6 +9,8 @@
# - Neutron networks, subnets and ports
# - Routers
# - Users and tenants
+# - Tacker VNFDs and VNFs
+# - Tacker SFCs and SFC classifiers
#
# Author:
# jose.lausuch@ericsson.com
@@ -21,14 +23,16 @@
#
import time
+
+import yaml
+
import functest.utils.functest_logger as ft_logger
import functest.utils.openstack_utils as os_utils
-import yaml
-import functest.utils.functest_constants as ft_constants
+from functest.utils.constants import CONST
logger = ft_logger.Logger("openstack_clean").getLogger()
-OS_SNAPSHOT_FILE = ft_constants.OPENSTACK_SNAPSHOT_FILE
+OS_SNAPSHOT_FILE = CONST.openstack_snapshot_file
def separator():
@@ -105,7 +109,7 @@ def remove_volumes(cinder_client, default_volumes):
for volume in volumes:
volume_id = getattr(volume, 'id')
- volume_name = getattr(volume, 'display_name')
+ volume_name = getattr(volume, 'name')
logger.debug("'%s', ID=%s " % (volume_name, volume_id))
if (volume_id not in default_volumes and
volume_name not in default_volumes.values()):
diff --git a/functest/utils/openstack_snapshot.py b/functest/utils/openstack_snapshot.py
index 4be1af443..e64030f75 100755
--- a/functest/utils/openstack_snapshot.py
+++ b/functest/utils/openstack_snapshot.py
@@ -20,15 +20,16 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
+import yaml
+
import functest.utils.functest_logger as ft_logger
import functest.utils.openstack_utils as os_utils
-import yaml
-import functest.utils.functest_constants as ft_constants
+from functest.utils.constants import CONST
logger = ft_logger.Logger("openstack_snapshot").getLogger()
-OS_SNAPSHOT_FILE = ft_constants.OPENSTACK_SNAPSHOT_FILE
+OS_SNAPSHOT_FILE = CONST.openstack_snapshot_file
def separator():
@@ -62,7 +63,7 @@ def get_volumes(cinder_client):
volumes = os_utils.get_volumes(cinder_client)
if volumes is not None:
for volume in volumes:
- dic_volumes.update({volume.id: volume.display_name})
+ dic_volumes.update({volume.id: volume.name})
return {'volumes': dic_volumes}
diff --git a/functest/utils/openstack_tacker.py b/functest/utils/openstack_tacker.py
index 6ab056683..f17b421e8 100644..100755
--- a/functest/utils/openstack_tacker.py
+++ b/functest/utils/openstack_tacker.py
@@ -21,7 +21,7 @@ logger = ft_logger.Logger("tacker_utils").getLogger()
def get_tacker_client():
- creds_tacker = os_utils.get_credentials('tacker')
+ creds_tacker = os_utils.get_credentials()
return tackerclient.Client(**creds_tacker)
diff --git a/functest/utils/openstack_utils.py b/functest/utils/openstack_utils.py
index 8f698d73d..64f18504d 100755
--- a/functest/utils/openstack_utils.py
+++ b/functest/utils/openstack_utils.py
@@ -14,16 +14,21 @@ import subprocess
import sys
import time
+from keystoneauth1 import loading
+from keystoneauth1 import session
from cinderclient import client as cinderclient
-import functest.utils.functest_logger as ft_logger
-import functest.utils.functest_utils as ft_utils
from glanceclient import client as glanceclient
-from keystoneclient.v2_0 import client as keystoneclient
-from neutronclient.v2_0 import client as neutronclient
from novaclient import client as novaclient
+from keystoneclient import client as keystoneclient
+from neutronclient.neutron import client as neutronclient
+
+import functest.utils.functest_logger as ft_logger
+import functest.utils.functest_utils as ft_utils
logger = ft_logger.Logger("openstack_utils").getLogger()
+DEFAULT_API_VERSION = '2'
+
# *********************************************
# CREDENTIALS
@@ -37,88 +42,72 @@ class MissingEnvVar(Exception):
return str.format("Please set the mandatory env var: {}", self.var)
+def is_keystone_v3():
+ keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
+ if (keystone_api_version is None or
+ keystone_api_version == '2'):
+ return False
+ else:
+ return True
+
+
+def get_rc_env_vars():
+ env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD']
+ 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
+
+
def check_credentials():
"""
Check if the OpenStack credentials (openrc) are sourced
"""
- env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_TENANT_NAME']
+ env_vars = get_rc_env_vars()
return all(map(lambda v: v in os.environ and os.environ[v], env_vars))
-def get_credentials(service):
- """Returns a creds dictionary filled with the following keys:
- * username
- * password/api_key (depending on the service)
- * tenant_name/project_id (depending on the service)
- * auth_url
- :param service: a string indicating the name of the service
- requesting the credentials.
+def get_env_cred_dict():
+ env_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 env_cred_dict
+
+
+def get_credentials(other_creds={}):
+ """Returns a creds dictionary filled with parsed from env
"""
creds = {}
+ env_vars = get_rc_env_vars()
+ env_cred_dict = get_env_cred_dict()
- keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
- if (keystone_api_version is None or
- keystone_api_version == '2'):
- keystone_v3 = False
- tenant_env = 'OS_TENANT_NAME'
- tenant = 'tenant_name'
- else:
- keystone_v3 = True
- tenant_env = 'OS_PROJECT_NAME'
- tenant = 'project_name'
-
- # Check that the env vars exists:
- envvars = ('OS_USERNAME', 'OS_PASSWORD', 'OS_AUTH_URL', tenant_env)
- for envvar in envvars:
+ for envvar in env_vars:
if os.getenv(envvar) is None:
raise MissingEnvVar(envvar)
+ 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)
- # Unfortunately, each of the OpenStack client will request slightly
- # different entries in their credentials dict.
- if service.lower() in ("nova", "cinder"):
- password = "api_key"
- tenant = "project_id"
- else:
- password = "password"
-
- # The most common way to pass these info to the script is to do it through
- # environment variables.
- creds.update({
- "username": os.environ.get("OS_USERNAME"),
- password: os.environ.get("OS_PASSWORD"),
- "auth_url": os.environ.get("OS_AUTH_URL"),
- tenant: os.environ.get(tenant_env)
- })
- if keystone_v3:
- if os.getenv('OS_USER_DOMAIN_NAME') is not None:
- creds.update({
- "user_domain_name": os.getenv('OS_USER_DOMAIN_NAME')
- })
- if os.getenv('OS_PROJECT_DOMAIN_NAME') is not None:
- creds.update({
- "project_domain_name": os.getenv('OS_PROJECT_DOMAIN_NAME')
- })
-
- if os.getenv('OS_ENDPOINT_TYPE') is not None:
- creds.update({
- "endpoint_type": os.environ.get("OS_ENDPOINT_TYPE")
- })
- if os.getenv('OS_REGION_NAME') is not None:
- creds.update({
- "region_name": os.environ.get("OS_REGION_NAME")
- })
- cacert = os.environ.get("OS_CACERT")
- if cacert is not None:
- # each openstack client uses differnt kwargs for this
- creds.update({"cacert": cacert,
- "ca_cert": cacert,
- "https_ca_cert": cacert,
- "https_cacert": cacert,
- "ca_file": cacert})
- creds.update({"insecure": "True", "https_insecure": "True"})
- if not os.path.isfile(cacert):
- logger.info("WARNING: The 'OS_CACERT' environment variable is "
- "set to %s but the file does not exist." % cacert)
return creds
@@ -132,66 +121,121 @@ def source_credentials(rc_file):
def get_credentials_for_rally():
- creds = get_credentials("keystone")
- keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
- if (keystone_api_version is None or
- keystone_api_version == '2'):
- admin_keys = ['username', 'tenant_name', 'password']
- else:
- admin_keys = ['username', 'password', 'user_domain_name',
- 'project_name', 'project_domain_name']
+ creds = get_credentials()
+ env_cred_dict = get_env_cred_dict()
+ rally_conf = {"type": "ExistingCloud", "admin": {}}
+ for key in creds:
+ if key == 'auth_url':
+ rally_conf[key] = creds[key]
+ else:
+ rally_conf['admin'][key] = creds[key]
endpoint_types = [('internalURL', 'internal'),
('publicURL', 'public'), ('adminURL', 'admin')]
- if 'endpoint_type' in creds.keys():
+
+ endpoint_type = os.getenv('OS_ENDPOINT_TYPE')
+ if endpoint_type is not None:
+ cred_key = env_cred_dict.get('OS_ENDPOINT_TYPE')
for k, v in endpoint_types:
- if creds['endpoint_type'] == k:
- creds['endpoint_type'] = v
- rally_conf = {"type": "ExistingCloud", "admin": {}}
- for key in creds:
- if key in admin_keys:
- rally_conf['admin'][key] = creds[key]
- else:
- rally_conf[key] = creds[key]
+ if endpoint_type == k:
+ rally_conf[cred_key] = v
+
+ region_name = os.getenv('OS_REGION_NAME')
+ if region_name is not None:
+ cred_key = env_cred_dict.get('OS_REGION_NAME')
+ rally_conf[cred_key] = region_name
return rally_conf
+def get_session_auth(other_creds={}):
+ loader = loading.get_plugin_loader('password')
+ creds = get_credentials(other_creds)
+ auth = loader.load_from_options(**creds)
+ return auth
+
+
+def get_endpoint(service_type, endpoint_type='publicURL'):
+ auth = get_session_auth()
+ return get_session().get_endpoint(auth=auth,
+ service_type=service_type,
+ endpoint_type=endpoint_type)
+
+
+def get_session(other_creds={}):
+ auth = get_session_auth(other_creds)
+ return session.Session(auth=auth)
+
+
# *********************************************
# CLIENTS
# *********************************************
-def get_keystone_client():
- creds_keystone = get_credentials("keystone")
- return keystoneclient.Client(**creds_keystone)
+def get_keystone_client_version():
+ api_version = os.getenv('OS_IDENTITY_API_VERSION')
+ if api_version is not None:
+ logger.info("OS_IDENTITY_API_VERSION is set in env as '%s'",
+ api_version)
+ return api_version
+ return DEFAULT_API_VERSION
+
+
+def get_keystone_client(other_creds={}):
+ sess = get_session(other_creds)
+ return keystoneclient.Client(get_keystone_client_version(), session=sess)
+
+def get_nova_client_version():
+ api_version = os.getenv('OS_COMPUTE_API_VERSION')
+ if api_version is not None:
+ logger.info("OS_COMPUTE_API_VERSION is set in env as '%s'",
+ api_version)
+ return api_version
+ return DEFAULT_API_VERSION
-def get_nova_client():
- creds_nova = get_credentials("nova")
- return novaclient.Client('2', **creds_nova)
+def get_nova_client(other_creds={}):
+ sess = get_session(other_creds)
+ return novaclient.Client(get_nova_client_version(), session=sess)
-def get_cinder_client():
- creds_cinder = get_credentials("cinder")
- creds_cinder.update({
- "service_type": "volume"
- })
- return cinderclient.Client('2', **creds_cinder)
+def get_cinder_client_version():
+ api_version = os.getenv('OS_VOLUME_API_VERSION')
+ if api_version is not None:
+ logger.info("OS_VOLUME_API_VERSION is set in env as '%s'",
+ api_version)
+ return api_version
+ return DEFAULT_API_VERSION
-def get_neutron_client():
- creds_neutron = get_credentials("neutron")
- return neutronclient.Client(**creds_neutron)
+def get_cinder_client(other_creds={}):
+ sess = get_session(other_creds)
+ return cinderclient.Client(get_cinder_client_version(), session=sess)
-def get_glance_client():
- keystone_client = get_keystone_client()
- glance_endpoint_type = 'publicURL'
- os_endpoint_type = os.getenv('OS_ENDPOINT_TYPE')
- if os_endpoint_type is not None:
- glance_endpoint_type = os_endpoint_type
- glance_endpoint = keystone_client.service_catalog.url_for(
- service_type='image', endpoint_type=glance_endpoint_type)
- return glanceclient.Client(1, glance_endpoint,
- token=keystone_client.auth_token)
+
+def get_neutron_client_version():
+ api_version = os.getenv('OS_NETWORK_API_VERSION')
+ if api_version is not None:
+ logger.info("OS_NETWORK_API_VERSION is set in env as '%s'",
+ api_version)
+ return api_version
+ return DEFAULT_API_VERSION
+
+
+def get_neutron_client(other_creds={}):
+ sess = get_session(other_creds)
+ return neutronclient.Client(get_neutron_client_version(), session=sess)
+
+
+def get_glance_client_version():
+ api_version = os.getenv('OS_IMAGE_API_VERSION')
+ if api_version is not None:
+ logger.info("OS_IMAGE_API_VERSION is set in env as '%s'", api_version)
+ return api_version
+ return DEFAULT_API_VERSION
+
+
+def get_glance_client(other_creds={}):
+ sess = get_session(other_creds)
+ return glanceclient.Client(get_glance_client_version(), session=sess)
# *********************************************
@@ -1070,38 +1114,29 @@ def get_image_id(glance_client, image_name):
def create_glance_image(glance_client, image_name, file_path, disk="qcow2",
- container="bare", public=True):
+ container="bare", public="public"):
if not os.path.isfile(file_path):
logger.error("Error: file %s does not exist." % file_path)
return None
try:
image_id = get_image_id(glance_client, image_name)
if image_id != '':
- if logger:
- logger.info("Image %s already exists." % image_name)
+ logger.info("Image %s already exists." % image_name)
else:
- if logger:
- logger.info("Creating image '%s' from '%s'..." % (image_name,
- file_path))
- try:
- properties = ft_utils.get_functest_config(
- 'general.image_properties')
- except ValueError:
- # image properties are not configured
- # therefore don't add any properties
- properties = {}
- with open(file_path) as fimage:
- image = glance_client.images.create(name=image_name,
- is_public=public,
- disk_format=disk,
- container_format=container,
- properties=properties,
- data=fimage)
+ logger.info("Creating image '%s' from '%s'..." % (image_name,
+ file_path))
+
+ image = glance_client.images.create(name=image_name,
+ visibility=public,
+ disk_format=disk,
+ container_format=container)
image_id = image.id
+ with open(file_path) as image_data:
+ glance_client.images.upload(image_id, image_data)
return image_id
except Exception, e:
logger.error("Error [create_glance_image(glance_client, '%s', '%s', "
- "'%s')]: %s" % (image_name, file_path, str(public), e))
+ "'%s')]: %s" % (image_name, file_path, public, e))
return None
@@ -1218,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)
@@ -1235,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:
@@ -1245,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:
@@ -1266,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"
@@ -1279,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'"
@@ -1292,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'"
@@ -1302,7 +1361,10 @@ def add_role_user(keystone_client, user_id, role_id, tenant_id):
def delete_tenant(keystone_client, tenant_id):
try:
- keystone_client.tenants.delete(tenant_id)
+ if is_keystone_v3():
+ keystone_client.projects.delete(tenant_id)
+ else:
+ keystone_client.tenants.delete(tenant_id)
return True
except Exception, e:
logger.error("Error [delete_tenant(keystone_client, '%s')]: %s"
diff --git a/run_unit_tests.sh b/run_unit_tests.sh
index ecd57d8ae..e0e6195cb 100755
--- a/run_unit_tests.sh
+++ b/run_unit_tests.sh
@@ -2,6 +2,13 @@
set -o errexit
set -o pipefail
+function clean_results_dir {
+ if [ -d "/home/opnfv/functest/results" ]
+ then
+ sudo rm -rf /home/opnfv/functest/results
+ fi
+}
+
# ******************************
# prepare the env for the tests
# ******************************
@@ -9,10 +16,7 @@ set -o pipefail
# 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
+clean_results_dir
# TODO clean that...
# Create log dir if needed
@@ -53,8 +57,11 @@ export CONFIG_FUNCTEST_YAML=$(pwd)/functest/ci/config_functest.yaml
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
@@ -66,9 +73,6 @@ deactivate
# clean
# *******
# Clean useless logs
-if [ -d "/home/opnfv/functest/results" ]
-then
- sudo rm -rf /home/opnfv/functest/results
-fi
+clean_results_dir
exit $rc
diff --git a/setup.py b/setup.py
index 58a9a4886..0c53ffbc9 100644
--- a/setup.py
+++ b/setup.py
@@ -1,25 +1,25 @@
-##############################################################################
-# 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
-##############################################################################
-
-from setuptools import setup, find_packages
-
-
-setup(
- name="functest",
- version="master",
- py_modules=['cli_base'],
- packages=find_packages(),
- include_package_data=True,
- package_data={
- },
- url="https://www.opnfv.org",
- entry_points={
- 'console_scripts': [
- 'functest=functest.cli.cli_base:cli'
- ],
- },
-)
+##############################################################################
+# 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
+##############################################################################
+
+from setuptools import setup, find_packages
+
+
+setup(
+ name="functest",
+ version="master",
+ py_modules=['cli_base'],
+ packages=find_packages(),
+ include_package_data=True,
+ package_data={
+ },
+ url="https://www.opnfv.org",
+ entry_points={
+ 'console_scripts': [
+ 'functest=functest.cli.cli_base:cli'
+ ],
+ },
+)
diff --git a/test-requirements.txt b/test-requirements.txt
index 8be8e2033..f724d5b16 100755
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -5,6 +5,7 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
#
+click==6.6
coverage==4.1
dnspython==1.15.0
gitpython==1.0.1
@@ -20,4 +21,4 @@ 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