summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docker/Dockerfile15
-rw-r--r--docker/Dockerfile.aarch6413
-rwxr-xr-xdocs/com/pres/Summit/Berlin-2016/summit-Berlin.html2
-rwxr-xr-xdocs/com/pres/Summit/Berlin-2016/testapi.html28
-rw-r--r--docs/release/release-notes/functest-release.rst (renamed from docs/release-notes/functest-release.rst)6
-rw-r--r--docs/release/release-notes/index.rst (renamed from docs/release-notes/index.rst)2
-rw-r--r--docs/testing/developer/devguide/index.rst (renamed from docs/devguide/index.rst)27
-rw-r--r--docs/testing/developer/internship/security_group/index.rst (renamed from docs/internship/security_group/index.rst)0
-rw-r--r--docs/testing/developer/internship/testapi_evolution/index.rst (renamed from docs/internship/testapi_evolution/index.rst)42
-rw-r--r--docs/testing/developer/internship/unit_tests/index.rst (renamed from docs/internship/unit_tests/index.rst)0
-rw-r--r--docs/testing/developer/internship/vnf_catalog/index.rst (renamed from docs/internship/vnf_catalog/index.rst)0
-rw-r--r--docs/testing/user/configguide/configguide.rst (renamed from docs/configguide/configguide.rst)2
-rw-r--r--docs/testing/user/configguide/index.rst (renamed from docs/configguide/index.rst)0
-rw-r--r--docs/testing/user/userguide/index.rst (renamed from docs/userguide/index.rst)0
-rw-r--r--docs/testing/user/userguide/introduction.rst (renamed from docs/userguide/introduction.rst)0
-rw-r--r--docs/testing/user/userguide/runfunctest.rst (renamed from docs/userguide/runfunctest.rst)2
-rw-r--r--docs/testing/user/userguide/troubleshooting.rst (renamed from docs/userguide/troubleshooting.rst)2
-rw-r--r--functest/ci/config_aarch64_patch.yaml8
-rwxr-xr-xfunctest/ci/config_functest.yaml16
-rwxr-xr-xfunctest/ci/config_patch.yaml6
-rwxr-xr-xfunctest/ci/exec_test.sh154
-rwxr-xr-xfunctest/ci/prepare_env.py58
-rwxr-xr-xfunctest/ci/run_tests.py28
-rwxr-xr-xfunctest/ci/testcases.yaml148
-rwxr-xr-xfunctest/ci/tier_builder.py1
-rwxr-xr-xfunctest/ci/tier_handler.py13
-rw-r--r--functest/core/pytest_suite_runner.py2
-rw-r--r--functest/core/vnf_base.py6
-rw-r--r--functest/opnfv_tests/features/barometer.py5
-rwxr-xr-xfunctest/opnfv_tests/features/security_scan.py4
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template2
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template2
-rw-r--r--functest/opnfv_tests/openstack/snaps/api_check.py9
-rw-r--r--functest/opnfv_tests/openstack/snaps/connection_check.py9
-rw-r--r--functest/opnfv_tests/openstack/snaps/health_check.py21
-rw-r--r--functest/opnfv_tests/openstack/snaps/smoke.py16
-rw-r--r--functest/opnfv_tests/openstack/snaps/snaps_test_runner.py30
-rw-r--r--functest/opnfv_tests/openstack/tempest/conf_utils.py24
-rw-r--r--functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt19
-rw-r--r--functest/opnfv_tests/openstack/tempest/tempest.py4
-rwxr-xr-xfunctest/opnfv_tests/sdn/odl/odl.py16
-rw-r--r--functest/opnfv_tests/sdn/onos/__init__.py0
-rw-r--r--functest/opnfv_tests/sdn/onos/onos.py225
-rw-r--r--functest/opnfv_tests/sdn/onos/teston/adapters/foundation.py38
-rwxr-xr-xfunctest/opnfv_tests/sdn/onos/teston/onos.py261
-rw-r--r--functest/opnfv_tests/vnf/ims/cloudify_ims.py2
-rw-r--r--functest/opnfv_tests/vnf/ims/orchestra_ims.py211
-rw-r--r--functest/opnfv_tests/vnf/ims/orchestra_ims.yaml14
-rw-r--r--functest/tests/unit/ci/__init__.py0
-rw-r--r--functest/tests/unit/ci/test_prepare_env.py347
-rw-r--r--functest/tests/unit/odl/test_odl.py26
-rw-r--r--functest/tests/unit/utils/test_openstack_utils.py58
-rw-r--r--functest/utils/functest_constants.py218
-rwxr-xr-xfunctest/utils/openstack_utils.py87
-rw-r--r--requirements.txt1
-rwxr-xr-xrun_unit_tests.sh10
-rw-r--r--test-requirements.txt1
57 files changed, 1219 insertions, 1022 deletions
diff --git a/docker/Dockerfile b/docker/Dockerfile
index de47e157a..bb54943df 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -14,7 +14,7 @@ LABEL version="0.1" description="OPNFV Functest Docker container"
# Environment variables
ARG BRANCH=master
ARG RALLY_TAG=0.8.1
-ARG TEMPEST_TAG=14.0.0
+ARG TEMPEST_TAG=15.0.0
ARG ODL_TAG=release/beryllium-sr4
ARG OPENSTACK_TAG=stable/mitaka
ARG KINGBIRD_TAG=0.2.2
@@ -54,6 +54,7 @@ libpq-dev \
libssl-dev \
libxml2-dev \
libxslt-dev \
+libzmq3-dev \
python-dev \
python-mock \
python-pip \
@@ -85,6 +86,7 @@ RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/doctor ${REPO
RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/ovno ${REPOS_DIR}/ovno
RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/promise ${REPOS_DIR}/promise
RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/netready ${REPOS_DIR}/netready
+RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/fds ${REPOS_DIR}/fds
RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/barometer ${REPOS_DIR}/barometer
RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/sfc ${REPOS_DIR}/sfc
RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/snaps ${REPOS_DIR}/snaps
@@ -108,10 +110,10 @@ RUN pip install -r ${REPOS_DIR}/tempest/requirements.txt
RUN cd ${FUNCTEST_REPO_DIR} \
&& pip install -r requirements.txt \
- && pip install .
+ && pip install -e .
RUN cd ${RELENG_MODULE_DIR} \
- && pip install .
+ && pip install -e .
RUN cd ${REPOS_DIR}/barometer \
&& pip install .
@@ -133,12 +135,11 @@ RUN pip install -e ${REPOS_DIR}/snaps/
# 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 .
+RUN cd ${REPOS_DIR}/sfc && pip install -e .
# SDNVPN integration
-RUN cd ${REPOS_DIR}/sdnvpn && pip install .
-
-RUN cd ${REPOS_DIR}/bgpvpn && pip install .
+RUN cd ${REPOS_DIR}/sdnvpn && pip install -e .
+RUN cd ${REPOS_DIR}/bgpvpn && pip install -e .
# Kingbird integration
RUN cd ${REPOS_DIR}/kingbird && pip install -e .
diff --git a/docker/Dockerfile.aarch64 b/docker/Dockerfile.aarch64
index a469801f3..4281dbdcf 100644
--- a/docker/Dockerfile.aarch64
+++ b/docker/Dockerfile.aarch64
@@ -14,7 +14,7 @@ LABEL version="0.1" description="OPNFV Functest Aarch64 Docker container"
# Environment variables
ARG BRANCH=master
ARG RALLY_TAG=0.8.1
-ARG TEMPEST_TAG=14.0.0
+ARG TEMPEST_TAG=15.0.0
ARG ODL_TAG=release/beryllium-sr4
ARG OPENSTACK_TAG=stable/mitaka
ARG KINGBIRD_TAG=0.2.2
@@ -105,10 +105,10 @@ RUN pip install -r ${REPOS_DIR}/tempest/requirements.txt
RUN cd ${FUNCTEST_REPO_DIR} \
&& pip install -r requirements.txt \
- && pip install .
+ && pip install -e .
RUN cd ${RELENG_MODULE_DIR} \
- && pip install .
+ && pip install -e .
RUN find ${FUNCTEST_REPO_DIR} -name "*.py" \
-not -path "*tests/unit*" |xargs grep __main__ |cut -d\: -f 1 |xargs chmod -c 755 \
@@ -127,12 +127,11 @@ RUN pip install -e ${REPOS_DIR}/snaps/
# 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 .
+RUN cd ${REPOS_DIR}/sfc && pip install -e .
# SDNVPN integration
-RUN cd ${REPOS_DIR}/sdnvpn && pip install .
-
-RUN cd ${REPOS_DIR}/bgpvpn && pip install .
+RUN cd ${REPOS_DIR}/sdnvpn && pip install -e .
+RUN cd ${REPOS_DIR}/bgpvpn && pip install -e .
# Kingbird integration
RUN cd ${REPOS_DIR}/kingbird && pip install -e .
diff --git a/docs/com/pres/Summit/Berlin-2016/summit-Berlin.html b/docs/com/pres/Summit/Berlin-2016/summit-Berlin.html
index 4173a86ac..8369443f7 100755
--- a/docs/com/pres/Summit/Berlin-2016/summit-Berlin.html
+++ b/docs/com/pres/Summit/Berlin-2016/summit-Berlin.html
@@ -230,7 +230,7 @@
## What's new?
* Slicing of the tests (healthcheck / Smoke / SDN controllers / Features / Components / VNFs)
* Better Test duration management
- * Refactoring (repo, case management, test API)
+ * Refactoring (repo, case management, TestAPI)
* Automatic reporting
* Dashboard evolution to ELK
* CLI
diff --git a/docs/com/pres/Summit/Berlin-2016/testapi.html b/docs/com/pres/Summit/Berlin-2016/testapi.html
index 7035d71df..16f97c44d 100755
--- a/docs/com/pres/Summit/Berlin-2016/testapi.html
+++ b/docs/com/pres/Summit/Berlin-2016/testapi.html
@@ -6,7 +6,7 @@
<title>OPNFV presentation</title>
- <meta name="description" content="Test API">
+ <meta name="description" content="TestAPI">
<meta name="author" content="Serena Feng">
<meta name="apple-mobile-web-app-capable" content="yes" />
@@ -42,7 +42,7 @@
<section data-background="../../../img/title-bg-berlin.png" data-background-transition="none">
<br><br><br><br><br>
- <h1>Test API</h1>
+ <h1>TestAPI</h1>
<h3>Clean, Easy, Complete</h3>
<br>
<h4>OPNFV testing community</h4>
@@ -52,7 +52,7 @@
<section data-markdown>
# Agenda
- * testAPI: what for?
+ * TestAPI: what for?
* API overview
* API evolution
* Roadmap
@@ -60,7 +60,7 @@
<section>
<section data-markdown>
- # test API: what for?
+ # TestAPI: what for?
</section>
<section data-markdown>
## Consistant view for
@@ -78,12 +78,12 @@
</section>
<section data-markdown>
<script type='text/template'>
- ## Achieve using testAPI
- * Uniform API: testAPI
+ ## Achieve using TestAPI
+ * Uniform API: TestAPI
* Uniform format: JSON
* Universal Location: http://testresults.opnfv.org
<aside class='notes'>
- By using testAPI, we hope to provide a uniform way of collection and saving test results to a universal location
+ By using TestAPI, we hope to provide a uniform way of collection and saving test results to a universal location
</aside>
</script>
</section>
@@ -101,11 +101,11 @@
</section>
<section data-markdown>
## Storage structure
- ![testapi](https://wiki.opnfv.org/download/attachments/2926452/results_collection_structure.png?version=1&modificationDate=1459196347000&api=v2 "OPNFV API page")
+ ![TestAPI](https://wiki.opnfv.org/download/attachments/2926452/results_collection_structure.png?version=1&modificationDate=1459196347000&api=v2 "OPNFV API page")
</section>
<section data-markdown>
## API in Brahmaputra
- ![testapi](../../../img/testapi0.png)
+ ![TestAPI](../../../img/testapi0.png)
https://wiki.opnfv.org/display/functest/Collection+Of+Test+Results
</section>
@@ -137,7 +137,7 @@
<aside class='notes'>
So you can discover and understand the capabilities of the service without
access to source code, documentation, or through network traffic inspection,
- and also you can interact with the testAPI directly through swagger website.
+ and also you can interact with the TestAPI directly through swagger website.
</aside>
</ul>
<p class="fragment fade-up"><b>All done in Colorado!</b></p>
@@ -152,7 +152,7 @@
<section>
<h2> URI changes...</h2>
<div style="text-align:left"">
- <p> testresults.opnfv.org/<span style="color:lightblue">testapi</span> => <br>testresults.opnfv.org/<span style="color:yellow">test/api/v1</span> </p>
+ <p> testresults.opnfv.org/<span style="color:lightblue">TestAPI</span> => <br>testresults.opnfv.org/<span style="color:yellow">test/api/v1</span> </p>
<p> /test/api/v1/<b>pods</b></p>
<p> /test/api/v1/<b>projects</b></p>
@@ -195,7 +195,7 @@
</section>
<section data-markdown>
http://testresults.opnfv.org/test/swagger/spec.html
- ![alt text](../../../img/testapi1.png "Test API swagger interface")
+ ![alt text](../../../img/testapi1.png "TestAPI swagger interface")
</section>
<section>
<h2>unit tests</h2>
@@ -223,8 +223,8 @@ OK
</section>
<section data-markdown>
## Roadmap
- * Dockerize testAPI
- * Automatic update of testAPI
+ * Dockerize TestAPI
+ * Automatic update of TestAPI
* Command Line Interface
* Automatic update for pods/projects/testcases
</section>
diff --git a/docs/release-notes/functest-release.rst b/docs/release/release-notes/functest-release.rst
index 07389bb5b..ce03047f6 100644
--- a/docs/release-notes/functest-release.rst
+++ b/docs/release/release-notes/functest-release.rst
@@ -32,7 +32,7 @@ Version history
+------------+----------+------------------+------------------------+
OPNFV Colorado Release
-=========================
+======================
Functest deals with functional testing of the OPNFV solution.
It includes test cases developed within the project and test cases developed in
@@ -99,7 +99,7 @@ Software
- The Functest Docker image: https://hub.docker.com/r/opnfv/functest (tag: colorado.1.0)
- - The testapi Docker image: https://hub.docker.com/r/opnfv/testapi (tag:colorado.1.0)
+ - The TestAPI Docker image: https://hub.docker.com/r/opnfv/testapi (tag:colorado.1.0)
Documents
@@ -120,7 +120,7 @@ Feature evolution
- refactoring of ODL functional tests (with upstream modifications)
- - refactoring of testapi (update, swagger documentation, dockerization)
+ - refactoring of TestAPI (update, swagger documentation, dockerization)
- jenkins logs improvement
diff --git a/docs/release-notes/index.rst b/docs/release/release-notes/index.rst
index 6c6d18109..25ee47713 100644
--- a/docs/release-notes/index.rst
+++ b/docs/release/release-notes/index.rst
@@ -1,3 +1,5 @@
+.. _functest-releasenotes:
+
**********************
Functest Release Notes
**********************
diff --git a/docs/devguide/index.rst b/docs/testing/developer/devguide/index.rst
index eee013678..ce5dc77be 100644
--- a/docs/devguide/index.rst
+++ b/docs/testing/developer/devguide/index.rst
@@ -14,7 +14,7 @@ Introduction
Functest is a project dealing with functional testing.
Functest produces its own internal test cases but can also be considered
as a framework to support feature and VNF onboarding project testing.
-Functest developed a test API and defined a test collection framework
+Functest developed a TestAPI and defined a test collection framework
that can be used by any OPNFV project.
Therefore there are many ways to contribute to Functest. You can:
@@ -197,7 +197,6 @@ functest/utils/
|-- config.py
|-- constants.py
|-- env.py
-|-- functest_constants.py
|-- functest_logger.py
|-- functest_utils.py
|-- openstack_clean.py
@@ -260,9 +259,9 @@ The Test result management can be summarized as follows::
| |
+----------------------+
-Test API description
---------------------
-The Test API is used to declare pods, projects, test cases and test
+TestAPI description
+-------------------
+The TestAPI is used to declare pods, projects, test cases and test
results. Pods are the pods used to run the tests.
The results pushed in the database are related to pods, projects and
cases. If you try to push results of test done on non referenced pod,
@@ -500,21 +499,21 @@ Scenarios:
The code of the API is hosted in the releng repository `[6]`_.
The static documentation of the API can be found at `[17]`_.
-The test API has been dockerized and may be installed locally in your
+The TestAPI has been dockerized and may be installed locally in your
lab. See `[15]`_ for details.
-The deployment of the test API has been automated.
+The deployment of the TestAPI has been automated.
A jenkins job manages:
- * the unit tests of the test api
+ * the unit tests of the TestAPI
* the creation of a new docker file
- * the deployment of the new test api
- * the archive of the old test api
+ * the deployment of the new TestAPI
+ * the archive of the old TestAPI
* the backup of the Mongo DB
-Test API Authorization
-~~~~~~~~~~~~~~~~~~~~~~
+TestAPI Authorization
+~~~~~~~~~~~~~~~~~~~~~
-PUT/DELETE/POST operations of the testapi now require token based authorization. The token needs
+PUT/DELETE/POST operations of the TestAPI now require token based authorization. The token needs
to be added in the request using a header 'X-Auth-Token' for access to the database.
e.g::
@@ -627,7 +626,7 @@ script can be found in `[16]`_.
For next versions, it was decided to integrated bitergia dashboard.
Bitergia already provides a dashboard for code and infrastructure.
A new Test tab will be added. The dataset will be built by consuming
-the test API.
+the TestAPI.
=======
diff --git a/docs/internship/security_group/index.rst b/docs/testing/developer/internship/security_group/index.rst
index d1cdbdd8f..d1cdbdd8f 100644
--- a/docs/internship/security_group/index.rst
+++ b/docs/testing/developer/internship/security_group/index.rst
diff --git a/docs/internship/testapi_evolution/index.rst b/docs/testing/developer/internship/testapi_evolution/index.rst
index 9cca9ebce..3038d0ac6 100644
--- a/docs/internship/testapi_evolution/index.rst
+++ b/docs/testing/developer/internship/testapi_evolution/index.rst
@@ -7,9 +7,9 @@ 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
-==================
+=================
+TestAPI evolution
+=================
Author: Sakala Venkata Krishna Rohit
Mentors: S. Feng, J.Lausuch, M.Richomme
@@ -17,10 +17,10 @@ Mentors: S. Feng, J.Lausuch, M.Richomme
Abstract
========
-The testapi is used by all the test opnfv projects to report results.
+The TestAPI is used by all the test opnfv projects to report results.
It is also used to declare projects, test cases and labs. A major refactoring
-has been done in Colorado with the introduction of swagger. The testapi is defined in Functest
-developer guide. The purpose of this project is to add more features to the testapi that automate
+has been done in Colorado with the introduction of swagger. The TestAPI is defined in Functest
+developer guide. The purpose of this project is to add more features to the TestAPI that automate
the tasks that are done manually now, though there are tasks other than automation.
Version history
@@ -48,33 +48,33 @@ documentation is as follows.
Problem Statement:
------------------
-The problem statement could be divided into pending features that needed to be added into testapi
+The problem statement could be divided into pending features that needed to be added into TestAPI
repo. The following were to be accomplished within the internship time frame.
-* **Add verification jenkins job for the testapi code**
+* **Add verification jenkins job for the TestAPI code**
The purpose of this job is to verify whehter the unit tests are successful or not with the
inclusion of the patchset submitted.
* **Automatic update of opnfv/testapi docker image**
- The docker image of testapi is hosted in the opnfv docker hub. To ensure that the testapi image
+ The docker image of TestAPI is hosted in the opnfv docker hub. To ensure that the TestAPI image
is always updated with the repository, automatic updation of the image is necessary and a job
is triggered whenever a new patch gets merged.
* **Automation deployment of testresults.opnfv.org/test/ website**
- In the same manner as the docker image of testapi is updated, the testapi website needs to be
+ In the same manner as the docker image of TestAPI is updated, the TestAPI website needs to be
in sync with the repository code. So, a job has been added to the opnfv jenkins ci for the
updation of the testresults website.
-* **Generate static documentation of testapi calls**
- The purpose of this is to give an static/offline view of testapi. If someone wants to have a
- look at the Restful apis of testapi, he/she does't need to go to the website, he can download
+* **Generate static documentation of TestAPI calls**
+ The purpose of this is to give an static/offline view of TestAPI. If someone wants to have a
+ look at the Restful APIs of TestAPI, he/she does't need to go to the website, he can download
a html page and view it anytime.
-* **Backup MongoDB of testapi**
+* **Backup MongoDB of TestAPI**
The mongoDB needs to be backed up every week. Till now it was done manually, but due to this
internship, it is now automated using a jenkins job.
-* **Add token based authorization to the testapi calls**
+* **Add token based authorization to the TestAPI calls**
The token based authorization was implemented to ensure that only ci_pods could access the
database. Authentication has been added to only delete/put/post requests.
@@ -82,7 +82,7 @@ Curation Phase:
---------------
The curation phase was the first 3 to 4 weeks of the internship. This phase was to get familiar
-with the testapi code and functionality and propose the solutions/tools for the tasks mentioned
+with the TestAPI code and functionality and propose the solutions/tools for the tasks mentioned
above. Swagger codegen was choosen out of the four tools proposed `[3]`_ for generating static
documentaion.
@@ -107,7 +107,7 @@ The progress and completion of the tasks is described in the below table.
| **Date** | **Comment** |
| | |
+--------------------------+------------------------------------------+
-| Nov 14th - Dec 31st | Understand Testapi code and the |
+| Nov 14th - Dec 31st | Understand TestAPI code and the |
| | requirements. |
+--------------------------+------------------------------------------+
| Jan 1st - Jan 7th | Add jenkins job to create static |
@@ -134,8 +134,8 @@ the internship. This section may help other developers in solving any errors cas
code written as a part of this internship.
-Test Api
---------
+TestAPI
+-------
What is the difference between defining data_file as "/etc/.." and "etc/.." in setup.cfg ?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -216,7 +216,7 @@ defined.
What job style should be used when there is a situation like one build should trigger other builds
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
or when different build scripts need to be run on different machines ?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MultiJob style should be used as it has phases where each phase can be taken as a build scipt and
can have its own parameters by which one can define the SLAVE_LABEL parameter.
@@ -234,4 +234,4 @@ _`[4]` : http://artifacts.opnfv.org/testapibackup.html
_`[5]` : http://artifacts.opnfv.org/releng/docs/testapi.html
-_`[6]` : http://artifacts.opnfv.org/functest/review/26047/devguide/index.html#test-api-authorization
+_`[6]` : http://artifacts.opnfv.org/functest/docs/devguide/index.html#test-api-authorization
diff --git a/docs/internship/unit_tests/index.rst b/docs/testing/developer/internship/unit_tests/index.rst
index f969aa72d..f969aa72d 100644
--- a/docs/internship/unit_tests/index.rst
+++ b/docs/testing/developer/internship/unit_tests/index.rst
diff --git a/docs/internship/vnf_catalog/index.rst b/docs/testing/developer/internship/vnf_catalog/index.rst
index df7633391..df7633391 100644
--- a/docs/internship/vnf_catalog/index.rst
+++ b/docs/testing/developer/internship/vnf_catalog/index.rst
diff --git a/docs/configguide/configguide.rst b/docs/testing/user/configguide/configguide.rst
index 08e089c2b..6bec89258 100644
--- a/docs/configguide/configguide.rst
+++ b/docs/testing/user/configguide/configguide.rst
@@ -392,7 +392,6 @@ follows::
| |-- check_os.sh
| |-- config_functest.yaml
| |-- config_patch.yaml
- | |-- exec_test.sh
| |-- generate_report.py
| |-- prepare_env.py
| |-- run_tests.py
@@ -427,7 +426,6 @@ follows::
|-- config.py
|-- constants.py
|-- env.py
- |-- functest_constants.py
|-- functest_logger.py
|-- functest_utils.py
|-- openstack
diff --git a/docs/configguide/index.rst b/docs/testing/user/configguide/index.rst
index f12739e31..f12739e31 100644
--- a/docs/configguide/index.rst
+++ b/docs/testing/user/configguide/index.rst
diff --git a/docs/userguide/index.rst b/docs/testing/user/userguide/index.rst
index 9436de2b9..9436de2b9 100644
--- a/docs/userguide/index.rst
+++ b/docs/testing/user/userguide/index.rst
diff --git a/docs/userguide/introduction.rst b/docs/testing/user/userguide/introduction.rst
index 4dfe79375..4dfe79375 100644
--- a/docs/userguide/introduction.rst
+++ b/docs/testing/user/userguide/introduction.rst
diff --git a/docs/userguide/runfunctest.rst b/docs/testing/user/userguide/runfunctest.rst
index b5c7191ca..e7ab84b26 100644
--- a/docs/userguide/runfunctest.rst
+++ b/docs/testing/user/userguide/runfunctest.rst
@@ -174,7 +174,7 @@ To execute a Test Tier or Test Case, the 'run' command is used::
2016-06-30 11:50:31,865 - run_tests - INFO - ============================================
2016-06-30 11:50:31,865 - run_tests - INFO - Running test case 'vping_ssh'...
2016-06-30 11:50:31,865 - run_tests - INFO - ============================================
- 2016-06-30 11:50:32,977 - vping_ssh - INFO - Creating image 'functest-vping' from '/home/opnfv/functest/data/cirros-0.3.4-x86_64-disk.img'...
+ 2016-06-30 11:50:32,977 - vping_ssh - INFO - Creating image 'functest-vping' from '/home/opnfv/functest/data/cirros-0.3.5-x86_64-disk.img'...
2016-06-30 11:50:45,470 - vping_ssh - INFO - Creating neutron network vping-net...
2016-06-30 11:50:47,645 - vping_ssh - INFO - Creating security group 'vPing-sg'...
2016-06-30 11:50:48,843 - vping_ssh - INFO - Using existing Flavor 'm1.small'...
diff --git a/docs/userguide/troubleshooting.rst b/docs/testing/user/userguide/troubleshooting.rst
index 1b7bf9b38..845501916 100644
--- a/docs/userguide/troubleshooting.rst
+++ b/docs/testing/user/userguide/troubleshooting.rst
@@ -100,7 +100,7 @@ In this case, proceed to create it manually. These are some hints::
--protocol tcp --port-range-min 80 --port-range-max 80 --remote-ip-prefix 0.0.0.0/0
The next step is to create the instances. The image used is located in
-*/home/opnfv/functest/data/cirros-0.3.4-x86_64-disk.img* and a Glance image is created
+*/home/opnfv/functest/data/cirros-0.3.5-x86_64-disk.img* and a Glance image is created
with the name **functest-vping**. If booting the instances fails (i.e. the status
is not **ACTIVE**), you can check why it failed by doing::
diff --git a/functest/ci/config_aarch64_patch.yaml b/functest/ci/config_aarch64_patch.yaml
index 9a345e3f7..b43b5a76c 100644
--- a/functest/ci/config_aarch64_patch.yaml
+++ b/functest/ci/config_aarch64_patch.yaml
@@ -5,10 +5,10 @@ os:
image_file_name: cirros-d161201-aarch64-disk.img
image_password: gocubsgo
- snaps_simple_healthcheck:
- disk_image: /home/opnfv/functest/data/cirros-d161201-aarch64-disk.img
- kernel_image: /home/opnfv/functest/data/cirros-d161201-aarch64-kernel
- ramdisk_image: /home/opnfv/functest/data/cirros-d161201-aarch64-initramfs
+ snaps_health_check:
+ disk_url: http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-disk.img
+ kernel_url: http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-kernel
+ ramdisk_url: http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-initramfs
extra_properties:
os_command_line: root=/dev/vdb1 rw rootwait console=tty0 console=ttyS0 console=ttyAMA0
hw_video_model: vga
diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml
index 489c395ff..b358a3323 100755
--- a/functest/ci/config_functest.yaml
+++ b/functest/ci/config_functest.yaml
@@ -5,8 +5,8 @@ general:
dir_odl: functest/opnfv_tests/sdn/odl
rally: functest/opnfv_tests/openstack/rally
tempest_cases: functest/opnfv_tests/openstack/tempest/custom_tests
- dir_onos: functest/opnfv_tests/sdn/onos/teston
- dir_onos_sfc: functest/opnfv_tests/sdn/onos/sfc
+ onos: functest/opnfv_tests/sdn/onos/teston
+ onos_sfc: functest/opnfv_tests/sdn/onos/sfc
# Absolute path
home: /home/opnfv
@@ -18,7 +18,7 @@ general:
repo_vims_test: /home/opnfv/repos/vnfs/vims-test
repo_sdnvpn: /home/opnfv/repos/sdnvpn
repo_sfc: /home/opnfv/repos/sfc
- dir_repo_onos: /home/opnfv/repos/onos
+ repo_onos: /home/opnfv/repos/onos
repo_promise: /home/opnfv/repos/promise
repo_netready: /home/opnfv/repos/netready
repo_barometer: /home/opnfv/repos/barometer
@@ -28,8 +28,9 @@ general:
repo_parser: /home/opnfv/repos/parser
repo_domino: /home/opnfv/repos/domino
repo_snaps: /home/opnfv/repos/snaps
+ repo_fds: /home/opnfv/repos/fds
repo_securityscan: /home/opnfv/repos/securityscanning
- repo_vrouter: /home/opnfv/repos/vrouter
+ repo_vrouter: /home/opnfv/repos/vnfs/vrouter
functest: /home/opnfv/functest
functest_test: /home/opnfv/repos/functest/functest/opnfv_tests
results: /home/opnfv/functest/results
@@ -38,13 +39,14 @@ general:
functest_data: /home/opnfv/functest/data
ims_data: /home/opnfv/functest/data/ims/
rally_inst: /home/opnfv/.rally
+ repo_kingbird: /home/opnfv/repos/kingbird
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_name: Cirros-0.3.5
+ image_file_name: cirros-0.3.5-x86_64-disk.img
image_disk_format: qcow2
image_username: cirros
image_password: cubswin:)
@@ -67,7 +69,7 @@ general:
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_image: /home/opnfv/functest/data/cirros-0.3.5-x86_64-disk.img
disk_format: qcow2
wait_time: 60
diff --git a/functest/ci/config_patch.yaml b/functest/ci/config_patch.yaml
index 46064a07f..d984a3f47 100755
--- a/functest/ci/config_patch.yaml
+++ b/functest/ci/config_patch.yaml
@@ -1,12 +1,12 @@
lxd:
general:
openstack:
- image_name: Cirros-0.3.4
- image_file_name: cirros-0.3.4-x86_64-lxc.tar.gz
+ image_name: Cirros-0.3.5
+ image_file_name: cirros-0.3.5-x86_64-lxc.tar.gz
image_disk_format: raw
healthcheck:
- disk_image: /home/opnfv/functest/data/cirros-0.3.4-x86_64-lxc.tar.gz
+ disk_image: /home/opnfv/functest/data/cirros-0.3.5-x86_64-lxc.tar.gz
disk_format: raw
fdio:
general:
diff --git a/functest/ci/exec_test.sh b/functest/ci/exec_test.sh
deleted file mode 100755
index aa0cfaf7e..000000000
--- a/functest/ci/exec_test.sh
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/bin/bash
-
-#
-# Author: Jose Lausuch (jose.lausuch@ericsson.com)
-# Morgan Richomme (morgan.richomme@orange.com)
-# Installs the Functest framework within the Docker container
-# and run the tests automatically
-#
-#
-# 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
-#
-
-usage="Script to trigger the tests automatically.
-
-usage:
- bash $(basename "$0") [-h|--help] [-t <test_name>]
-
-where:
- -h|--help show this help text
- -r|--report push results to database (false by default)
- -s|--serial run Tempest tests in one thread
- -t|--test run specific test case
- <test_name>"
-
-
-report=""
-serial=false
-
-# Get the list of runnable tests
-# Check if we are in CI mode
-debug=""
-if [[ "${CI_DEBUG,,}" == "true" ]];then
- debug="--debug"
-fi
-
-FUNCTEST_REPO_DIR=${REPOS_DIR}/functest
-FUNCTEST_TEST_DIR=${REPOS_DIR}/functest/functest/opnfv_tests
-FUNCTEST_CONF_DIR=/home/opnfv/functest/conf
-
-export PYTHONUNBUFFERED=1
-
-function odl_tests(){
- keystone_ip=$(openstack catalog show identity |grep publicURL| cut -f3 -d"/" | cut -f1 -d":")
- neutron_ip=$(openstack catalog show network | grep publicURL | cut -f3 -d"/" | cut -f1 -d":")
- odl_ip=${neutron_ip}
- odl_port=8080
- odl_restport=8181
- if [ "$INSTALLER_TYPE" == "fuel" ]; then
- odl_port=8282
- elif [ "$INSTALLER_TYPE" == "apex" ]; then
- odl_ip=$SDN_CONTROLLER_IP
- odl_port=8081
- odl_restport=8081
- elif [ "$INSTALLER_TYPE" == "netvirt" ]; then
- odl_ip=$SDN_CONTROLLER_IP
- odl_port=8081
- odl_restport=8081
- elif [ "$INSTALLER_TYPE" == "joid" ]; then
- odl_ip=$SDN_CONTROLLER
- elif [ "$INSTALLER_TYPE" == "compass" ]; then
- odl_port=8181
- else
- odl_ip=$SDN_CONTROLLER_IP
- fi
-}
-
-
-
-function run_test(){
- test_name=$1
- serial_flag=""
- if [ $serial == "true" ]; then
- serial_flag="-s"
- fi
-
- case $test_name in
- "healthcheck")
- ${FUNCTEST_TEST_DIR}/openstack/healthcheck/healthcheck.sh
- ;;
- "odl")
- odl_tests
- [[ "$report" == "-r" ]] && args=-p
- ${FUNCTEST_TEST_DIR}/sdn/odl/odl.py \
- --keystoneip $keystone_ip \
- --neutronip $neutron_ip \
- --odlip $odl_ip \
- --odlrestconfport $odl_restport \
- --odlwebport $odl_port \
- --ospassword ${OS_PASSWORD} \
- --ostenantname ${OS_TENANT_NAME} \
- --osusername ${OS_USERNAME} \
- ${args}
- ;;
- "onos")
- python ${FUNCTEST_TEST_DIR}/sdn/onos/teston/onos.py
- ;;
- "onos_sfc")
- python ${FUNCTEST_TEST_DIR}/sdn/onos/teston/onos.py -t sfc
- ;;
- "ovno")
- # suite under rewritting for colorado
- # no need to run anything until refactoring done
- # ${REPOS_DIR}/ovno/Testcases/RunTests.sh
- ;;
- *)
- echo "The test case '${test_name}' does not exist."
- exit 1
- esac
-
- if [[ $? != 0 ]]; then exit 1
- else exit 0
- fi
-}
-
-
-# Parse parameters
-while [[ $# > 0 ]]
- do
- key="$1"
- case $key in
- -h|--help)
- echo "$usage"
- exit 0
- shift
- ;;
- -r|--report)
- report="-r"
- ;;
- -s|--serial)
- serial=true
- ;;
- -t|--test|--tests)
- TEST="$2"
- shift
- ;;
- *)
- echo "unknown option $1 $2"
- exit 1
- ;;
- esac
- shift # past argument or value
-done
-
-
-# Source credentials
-echo "Sourcing Credentials ${creds} to run the test.."
-source ${creds}
-
-
-# Run test
-run_test $TEST
diff --git a/functest/ci/prepare_env.py b/functest/ci/prepare_env.py
index f5bae6a04..724ea14df 100755
--- a/functest/ci/prepare_env.py
+++ b/functest/ci/prepare_env.py
@@ -31,6 +31,7 @@ logger = ft_logger.Logger("prepare_env").getLogger()
handler = None
# set the architecture to default
pod_arch = None
+arch_filter = ['aarch64']
CONFIG_FUNCTEST_PATH = CONST.CONFIG_FUNCTEST_YAML
CONFIG_PATCH_PATH = os.path.join(os.path.dirname(
@@ -115,24 +116,28 @@ def get_deployment_handler():
'functest/ci/installer_params.yaml')
if (CONST.INSTALLER_IP and CONST.INSTALLER_TYPE and
CONST.INSTALLER_TYPE in opnfv_constants.INSTALLERS):
- installer_params = ft_utils.get_parameter_from_yaml(
- CONST.INSTALLER_TYPE, installer_params_yaml)
-
- user = installer_params.get('user', None)
- password = installer_params.get('password', None)
- pkey = installer_params.get('pkey', None)
-
try:
- handler = factory.Factory.get_handler(
- installer=CONST.INSTALLER_TYPE,
- installer_ip=CONST.INSTALLER_IP,
- installer_user=user,
- installer_pwd=password,
- pkey_file=pkey)
- if handler:
- pod_arch = handler.get_arch()
- except Exception as e:
- logger.debug("Cannot get deployment information. %s" % e)
+ installer_params = ft_utils.get_parameter_from_yaml(
+ CONST.INSTALLER_TYPE, installer_params_yaml)
+ except ValueError as e:
+ logger.debug('Printing deployment info is not supported for %s' %
+ CONST.INSTALLER_TYPE)
+ logger.debug(e)
+ else:
+ user = installer_params.get('user', None)
+ password = installer_params.get('password', None)
+ pkey = installer_params.get('pkey', None)
+ try:
+ handler = factory.Factory.get_handler(
+ installer=CONST.INSTALLER_TYPE,
+ installer_ip=CONST.INSTALLER_IP,
+ installer_user=user,
+ installer_pwd=password,
+ pkey_file=pkey)
+ if handler:
+ pod_arch = handler.get_arch()
+ except Exception as e:
+ logger.debug("Cannot get deployment information. %s" % e)
def create_directories():
@@ -196,8 +201,7 @@ def source_rc_file():
raise Exception("The file %s is empty." % CONST.openstack_creds)
logger.info("Sourcing the OpenStack RC file...")
- os_utils.source_credentials(
- CONST.openstack_creds)
+ os_utils.source_credentials(CONST.openstack_creds)
for key, value in os.environ.iteritems():
if re.search("OS_", key):
if key == 'OS_AUTH_URL':
@@ -210,10 +214,15 @@ def source_rc_file():
CONST.OS_PASSWORD = value
-def patch_config_file(patch_file_path, arch_filter=None):
- if arch_filter and pod_arch not in arch_filter:
- return
+def patch_config_file():
+ patch_file(CONFIG_PATCH_PATH)
+
+ if pod_arch and pod_arch in arch_filter:
+ patch_file(CONFIG_AARCH64_PATCH_PATH)
+
+def patch_file(patch_file_path):
+ logger.debug('Updating file: %s', patch_file_path)
with open(patch_file_path) as f:
patch_file = yaml.safe_load(f)
@@ -250,7 +259,7 @@ def verify_deployment():
def install_rally():
print_separator()
- if 'aarch64' in pod_arch:
+ if pod_arch and pod_arch in arch_filter:
logger.info("Apply aarch64 specific to rally config...")
with open(RALLY_AARCH64_PATCH_PATH, "r") as f:
rally_patch_conf = f.read()
@@ -350,8 +359,7 @@ def main(**kwargs):
get_deployment_handler()
create_directories()
source_rc_file()
- patch_config_file(CONFIG_PATCH_PATH)
- patch_config_file(CONFIG_AARCH64_PATCH_PATH, 'aarch64')
+ patch_config_file()
verify_deployment()
install_rally()
install_tempest()
diff --git a/functest/ci/run_tests.py b/functest/ci/run_tests.py
index f920e70d8..4a47ba570 100755
--- a/functest/ci/run_tests.py
+++ b/functest/ci/run_tests.py
@@ -19,7 +19,6 @@ import sys
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.openstack_clean as os_clean
@@ -32,13 +31,6 @@ from functest.utils.constants import CONST
logger = ft_logger.Logger("run_tests").getLogger()
-""" global variables """
-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 Result.EX_ERROR
-
-
class Result(enum.Enum):
EX_OK = os.EX_OK
EX_ERROR = -1
@@ -91,16 +83,12 @@ def source_rc_file():
for key, value in os.environ.iteritems():
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
CONST.OS_PASSWORD = value
@@ -119,7 +107,7 @@ def update_test_info(test_name, result, duration):
"duration": duration})
-def get_run_dict_if_defined(testname):
+def get_run_dict(testname):
try:
dict = ft_utils.get_dict_by_test(testname)
if not dict:
@@ -143,7 +131,7 @@ def run_test(test, tier_name, testcases=None):
logger.debug("\n%s" % test)
source_rc_file()
- if GlobalVariables.CLEAN_FLAG:
+ if test.needs_clean() and GlobalVariables.CLEAN_FLAG:
generate_os_snapshot()
flags = (" -t %s" % (test_name))
@@ -151,12 +139,13 @@ def run_test(test, tier_name, testcases=None):
flags += " -r"
result = testcase_base.TestcaseBase.EX_RUN_ERROR
- run_dict = get_run_dict_if_defined(test_name)
+ run_dict = get_run_dict(test_name)
if run_dict:
try:
module = importlib.import_module(run_dict['module'])
cls = getattr(module, run_dict['class'])
test_case = cls()
+
try:
kwargs = run_dict['args']
result = test_case.run(**kwargs)
@@ -173,14 +162,11 @@ def run_test(test, tier_name, testcases=None):
logger.exception("Cannot get class {}".format(
run_dict['class']))
else:
- cmd = ("%s%s" % (EXEC_SCRIPT, flags))
- logger.info("Executing command {} because {} "
- "doesn't implement the new framework".format(
- cmd, test_name))
- result = ft_utils.execute_command(cmd)
+ raise Exception("Cannot import the class for the test case.")
- if GlobalVariables.CLEAN_FLAG:
+ if test.needs_clean() and GlobalVariables.CLEAN_FLAG:
cleanup()
+
end = datetime.datetime.now()
duration = (end - start).seconds
duration_str = ("%02d:%02d" % divmod(duration, 60))
diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml
index ed3a0b843..767380fc2 100755
--- a/functest/ci/testcases.yaml
+++ b/functest/ci/testcases.yaml
@@ -8,24 +8,10 @@ tiers:
operations in the VIM.
testcases:
-
- name: snaps_health_check
- criteria: 'status == "PASS"'
- blocking: true
- description: >-
- This test case creates executes the SimpleHealthCheck
- Python test class which creates an, image, flavor, network,
- and Cirros VM instance and observes the console output to
- validate the single port obtains the correct IP address.
- dependencies:
- installer: ''
- scenario: '^((?!lxd).)*$'
- run:
- module: 'functest.opnfv_tests.openstack.snaps.health_check'
- class: 'HealthCheck'
- -
name: connection_check
criteria: 'status == "PASS"'
blocking: true
+ clean_flag: false
description: >-
This test case verifies the retrieval of OpenStack clients:
Keystone, Glance, Neutron and Nova and may perform some
@@ -44,6 +30,7 @@ tiers:
name: api_check
criteria: 'status == "PASS"'
blocking: true
+ clean_flag: false
description: >-
This test case verifies the retrieval of OpenStack clients:
Keystone, Glance, Neutron and Nova and may perform some
@@ -57,6 +44,22 @@ tiers:
run:
module: 'functest.opnfv_tests.openstack.snaps.api_check'
class: 'ApiCheck'
+ -
+ name: snaps_health_check
+ criteria: 'status == "PASS"'
+ blocking: true
+ clean_flag: false
+ description: >-
+ This test case creates executes the SimpleHealthCheck
+ Python test class which creates an, image, flavor, network,
+ and Cirros VM instance and observes the console output to
+ validate the single port obtains the correct IP address.
+ dependencies:
+ installer: ''
+ scenario: '^((?!lxd).)*$'
+ run:
+ module: 'functest.opnfv_tests.openstack.snaps.health_check'
+ class: 'HealthCheck'
-
name: smoke
order: 1
@@ -68,13 +71,14 @@ tiers:
name: vping_ssh
criteria: 'status == "PASS"'
blocking: true
+ clean_flag: true
description: >-
This test case verifies: 1) SSH to an instance using floating
IPs over the public network. 2) Connectivity between 2 instances
over a private network.
dependencies:
installer: ''
- scenario: '^((?!bgpvpn|odl_l3).)*$'
+ scenario: '^((?!odl_l3).)*$'
run:
module: 'functest.opnfv_tests.openstack.vping.vping_ssh'
class: 'VPingSSH'
@@ -83,6 +87,7 @@ tiers:
name: vping_userdata
criteria: 'status == "PASS"'
blocking: true
+ clean_flag: true
description: >-
This test case verifies: 1) Boot a VM with given userdata.
2) Connectivity between 2 instances over a private network.
@@ -97,6 +102,7 @@ tiers:
name: tempest_smoke_serial
criteria: 'success_rate == 100%'
blocking: false
+ clean_flag: false
description: >-
This test case runs the smoke subset of the OpenStack
Tempest suite. The list of test cases is generated by
@@ -113,12 +119,13 @@ tiers:
name: rally_sanity
criteria: 'success_rate == 100%'
blocking: false
+ clean_flag: false
description: >-
This test case runs a sub group of tests of the OpenStack
Rally suite in smoke mode.
dependencies:
installer: ''
- scenario: '^((?!bgpvpn).)*$'
+ scenario: ''
run:
module: 'functest.opnfv_tests.openstack.rally.rally'
class: 'RallySanity'
@@ -127,6 +134,7 @@ tiers:
name: odl
criteria: 'success_rate == 100%'
blocking: true
+ clean_flag: false
description: >-
Test Suite for the OpenDaylight SDN Controller. It
integrates some test suites from upstream using
@@ -146,14 +154,15 @@ tiers:
name: odl_netvirt
criteria: 'success_rate == 100%'
blocking: true
+ clean_flag: false
description: >-
Test Suite for the OpenDaylight SDN Controller when
the NetVirt features are installed. It integrates
some test suites from upstream using Robot as the
test framework.
dependencies:
- installer: ''
- scenario: 'netvirt'
+ installer: 'apex'
+ scenario: 'os-odl_l3-nofeature'
run:
module: 'functest.opnfv_tests.sdn.odl.odl'
class: 'ODLTests'
@@ -164,9 +173,29 @@ tiers:
- /home/opnfv/repos/odl_test/csit/suites/openstack/connectivity
-
+ name: fds
+ criteria: 'success_rate == 100%'
+ blocking: false
+ clean_flag: false
+ description: >-
+ Test Suite for the OpenDaylight SDN Controller when GBP features are
+ installed. It integrates some test suites from upstream using
+ Robot as the test framework.
+ dependencies:
+ installer: 'apex'
+ scenario: 'odl_l2-fdio'
+ run:
+ module: 'functest.opnfv_tests.sdn.odl.odl'
+ class: 'ODLTests'
+ args:
+ suites:
+ - /home/opnfv/repos/fds/testing/robot
+
+ -
name: onos
criteria: 'status == "PASS"'
blocking: true
+ clean_flag: true
description: >-
Test Suite for the ONOS SDN Controller. It integrates
some test suites from upstream using TestON as the test
@@ -174,12 +203,15 @@ tiers:
dependencies:
installer: ''
scenario: 'onos'
-
+ run:
+ module: 'functest.opnfv_tests.sdn.onos.onos'
+ class: 'Onos'
-
name: snaps_smoke
criteria: 'status == "PASS"'
blocking: false
+ clean_flag: false
description: >-
This test case contains tests that setup and destroy
environments with VMs with and without Floating IPs
@@ -191,7 +223,7 @@ tiers:
dependencies:
installer: '^((?!netvirt).)*$'
- scenario: ''
+ scenario: '^((?!lxd).)*$'
run:
module: 'functest.opnfv_tests.openstack.snaps.smoke'
class: 'SnapsSmoke'
@@ -208,6 +240,7 @@ tiers:
name: promise
criteria: 'success_rate == 100%'
blocking: false
+ clean_flag: true
description: >-
Test suite from Promise project.
dependencies:
@@ -221,6 +254,7 @@ tiers:
name: doctor
criteria: 'status == "PASS"'
blocking: false
+ clean_flag: true
description: >-
Test suite from Doctor project.
dependencies:
@@ -234,6 +268,7 @@ tiers:
name: bgpvpn
criteria: 'status == "PASS"'
blocking: false
+ clean_flag: true
description: >-
Test suite from SDNVPN project.
dependencies:
@@ -247,6 +282,7 @@ tiers:
name: security_scan
criteria: 'status == "PASS"'
blocking: false
+ clean_flag: true
description: >-
Simple Security Scan
dependencies:
@@ -259,6 +295,7 @@ tiers:
# name: copper
# criteria: 'status == "PASS"'
# blocking: false
+# clean_flag: true
# description: >-
# Test suite for policy management based on OpenStack Congress
# dependencies:
@@ -271,6 +308,7 @@ tiers:
name: multisite
criteria: 'success_rate == 100%'
blocking: false
+ clean_flag: false
description: >-
Test suite from kingbird
dependencies:
@@ -283,6 +321,7 @@ tiers:
name: odl-sfc
criteria: 'status == "PASS"'
blocking: false
+ clean_flag: true
description: >-
Test suite for odl-sfc to test two chains and two SFs
dependencies:
@@ -295,15 +334,20 @@ tiers:
name: onos_sfc
criteria: 'status == "PASS"'
blocking: true
+ clean_flag: true
description: >-
Test Suite for onos-sfc to test sfc function.
dependencies:
installer: ''
scenario: 'onos-sfc'
+ run:
+ module: 'functest.opnfv_tests.sdn.onos.onos'
+ class: 'OnosSfc'
-
name: parser
criteria: 'ret == 0'
blocking: false
+ clean_flag: true
description: >-
Test suite from Parser project.
dependencies:
@@ -316,6 +360,7 @@ tiers:
name: domino
criteria: 'status == "PASS"'
blocking: false
+ clean_flag: true
description: >-
Test suite from Domino project.
dependencies:
@@ -325,21 +370,10 @@ tiers:
module: 'functest.opnfv_tests.features.domino'
class: 'Domino'
-
- name: orchestra
- criteria: 'ret == 0'
- blocking: false
- description: >-
- Test OpenBaton (Orchestra) stack
- dependencies:
- installer: 'joid'
- scenario: 'unknown'
- run:
- module: 'functest.opnfv_tests.features.orchestrator.orchestra'
- class: 'OpenbatonOrchestrator'
- -
name: netready
criteria: 'status == "PASS"'
blocking: false
+ clean_flag: true
description: >-
Test suite from Netready project.
dependencies:
@@ -352,6 +386,7 @@ tiers:
name: barometer
criteria: 'status == "PASS"'
blocking: false
+ clean_flag: true
description: >-
Test suite for the Barometer project. Separate tests verify the
proper configuration and functionality of the following
@@ -374,6 +409,7 @@ tiers:
# name: tempest_full_parallel
# criteria: 'success_rate >= 80%'
# blocking: false
+# clean_flag: false
# description: >-
# The list of test cases is generated by
# Tempest automatically and depends on the parameters of
@@ -388,6 +424,7 @@ tiers:
name: tempest_defcore
criteria: 'success_rate == 100%'
blocking: false
+ clean_flag: false
description: >-
This is the set of Tempest test cases created by OpenStack
Interop Working Group for certification purposes.
@@ -401,6 +438,7 @@ tiers:
name: tempest_custom
criteria: 'success_rate == 100%'
blocking: false
+ clean_flag: false
description: >-
The test case allows running a customized list of tempest
test cases defined in a file under
@@ -417,6 +455,7 @@ tiers:
# name: rally_full
# criteria: 'success_rate >= 90%'
# blocking: false
+# clean_flag: false
# description: >-
# This test case runs the full suite of scenarios of the OpenStack
# Rally suite using several threads and iterations.
@@ -438,6 +477,7 @@ tiers:
name: cloudify_ims
criteria: 'status == "PASS"'
blocking: false
+ clean_flag: true
description: >-
This test case deploys an OpenSource vIMS solution from Clearwater
using the Cloudify orchestrator. It also runs some signaling traffic.
@@ -447,36 +487,24 @@ tiers:
run:
module: 'functest.opnfv_tests.vnf.ims.cloudify_ims'
class: 'ImsVnf'
- -
- name: aaa
- criteria: 'ret == 0'
- blocking: false
- description: >-
- Test suite from Parser project.
- dependencies:
- installer: ''
- scenario: ''
- run:
- module: 'functest.opnfv_tests.vnf.aaa.aaa'
- class: 'AaaVnf'
-
- -
- name: juju_epc
- criteria: 'ret == 0'
- blocking: false
- description: >-
- Test suite from OAI project, vEPC deployed with Juju.
- dependencies:
- installer: 'unknown'
- scenario: 'unknown'
- run:
- module: 'functest.opnfv_tests.vnf.epc.epc'
- class: 'EpcVnf'
-
+# -
+# name: aaa
+# criteria: 'ret == 0'
+# blocking: false
+# clean_flag: true
+# description: >-
+# Test suite from Parser project.
+# dependencies:
+# installer: ''
+# scenario: ''
+# run:
+# module: 'functest.opnfv_tests.vnf.aaa.aaa'
+# class: 'AaaVnf'
-
name: orchestra_ims
criteria: 'ret == 0'
blocking: false
+ clean_flag: true
description: >-
VNF deployment with OpenBaton (Orchestra)
dependencies:
@@ -490,6 +518,7 @@ tiers:
name: opera_ims
criteria: 'ret == 0'
blocking: false
+ clean_flag: true
description: >-
Evolution of vIMS
dependencies:
@@ -503,6 +532,7 @@ tiers:
name: vyos_vrouter
criteria: 'status == "PASS"'
blocking: false
+ clean_flag: true
description: >-
This test case is vRouter testing.
dependencies:
diff --git a/functest/ci/tier_builder.py b/functest/ci/tier_builder.py
index dae7c73e8..f4c6f70fd 100755
--- a/functest/ci/tier_builder.py
+++ b/functest/ci/tier_builder.py
@@ -50,6 +50,7 @@ class TierBuilder(object):
dependency=dep,
criteria=dic_testcase['criteria'],
blocking=dic_testcase['blocking'],
+ clean_flag=dic_testcase['clean_flag'],
description=dic_testcase['description'])
if testcase.is_compatible(self.ci_installer, self.ci_scenario):
tier.add_test(testcase)
diff --git a/functest/ci/tier_handler.py b/functest/ci/tier_handler.py
index 127986bf3..6b4864b5b 100755
--- a/functest/ci/tier_handler.py
+++ b/functest/ci/tier_handler.py
@@ -104,12 +104,18 @@ class Tier(object):
class TestCase(object):
- def __init__(self, name, dependency, criteria, blocking, description=""):
+ def __init__(self, name,
+ dependency,
+ criteria,
+ blocking,
+ clean_flag,
+ description=""):
self.name = name
self.dependency = dependency
- self.description = description
self.criteria = criteria
self.blocking = blocking
+ self.clean_flag = clean_flag
+ self.description = description
@staticmethod
def is_none(item):
@@ -138,6 +144,9 @@ class TestCase(object):
def is_blocking(self):
return self.blocking
+ def needs_clean(self):
+ return self.clean_flag
+
def __str__(self):
lines = split_text(self.description, LINE_LENGTH - 6)
diff --git a/functest/core/pytest_suite_runner.py b/functest/core/pytest_suite_runner.py
index c168d7d93..f0ae265a4 100644
--- a/functest/core/pytest_suite_runner.py
+++ b/functest/core/pytest_suite_runner.py
@@ -1,5 +1,3 @@
-#!/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
diff --git a/functest/core/vnf_base.py b/functest/core/vnf_base.py
index 9438dca10..daf8b8061 100644
--- a/functest/core/vnf_base.py
+++ b/functest/core/vnf_base.py
@@ -79,7 +79,8 @@ class VnfOnBoardingBase(base.TestcaseBase):
self.details['vnf']['result'] = res_deploy_vnf['result']
self.details['vnf']['duration'] = round(
vnf_ready_time - orchestrator_ready_time, 1)
- except:
+ except Exception:
+ self.logger.error("Error during VNF deployment", exc_info=True)
raise Exception("Error during VNF deployment")
# Test VNF
@@ -91,7 +92,8 @@ class VnfOnBoardingBase(base.TestcaseBase):
self.details['test_vnf']['result'] = res_test_vnf['result']
self.details['test_vnf']['duration'] = round(
test_vnf_done_time - vnf_ready_time, 1)
- except:
+ except Exception:
+ self.logger.error("Error when running VNF tests", exc_info=True)
raise Exception("Error when running VNF tests")
# Clean the system
diff --git a/functest/opnfv_tests/features/barometer.py b/functest/opnfv_tests/features/barometer.py
index aec2bce5d..32067284b 100644
--- a/functest/opnfv_tests/features/barometer.py
+++ b/functest/opnfv_tests/features/barometer.py
@@ -6,11 +6,9 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
+from baro_tests import collectd
import functest.core.feature_base as base
-import functest.utils.functest_logger as ft_logger
-
-from baro_tests import collectd
class BarometerCollectd(base.FeatureBase):
@@ -22,7 +20,6 @@ class BarometerCollectd(base.FeatureBase):
super(BarometerCollectd, self).__init__(project='barometer',
case='barometercollectd',
repo='dir_repo_barometer')
- self.logger = ft_logger.Logger("BarometerCollectd").getLogger()
def execute(self):
return collectd.main(self.logger)
diff --git a/functest/opnfv_tests/features/security_scan.py b/functest/opnfv_tests/features/security_scan.py
index 2db44175d..58f0ec748 100755
--- a/functest/opnfv_tests/features/security_scan.py
+++ b/functest/opnfv_tests/features/security_scan.py
@@ -17,8 +17,8 @@ class SecurityScan(base.FeatureBase):
super(SecurityScan, self).__init__(project='securityscanning',
case='security_scan',
repo='dir_repo_securityscan')
- self.cmd = ('bash {0} && '
+ self.cmd = ('. {0}/stackrc && '
'cd {1} && '
'python security_scan.py --config config.ini && '
- 'cd -'.format(CONST.openstack_creds,
+ 'cd -'.format(CONST.dir_functest_conf,
self.repo))
diff --git a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
index 909f45d21..ed5e61fe0 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
+++ b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
@@ -7,7 +7,7 @@ parameters:
default: public
image:
type: string
- default: cirros-0.3.4-x86_64-uec
+ default: cirros-0.3.5-x86_64-uec
flavor:
type: string
default: m1.tiny
diff --git a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
index 826ca9dae..116b5bb6c 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
+++ b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
@@ -4,7 +4,7 @@ parameters:
# set all correct defaults for parameters before launch test
image:
type: string
- default: cirros-0.3.4-x86_64-uec
+ default: cirros-0.3.5-x86_64-uec
flavor:
type: string
default: m1.tiny
diff --git a/functest/opnfv_tests/openstack/snaps/api_check.py b/functest/opnfv_tests/openstack/snaps/api_check.py
index 17d05b922..ad77d9be3 100644
--- a/functest/opnfv_tests/openstack/snaps/api_check.py
+++ b/functest/opnfv_tests/openstack/snaps/api_check.py
@@ -9,12 +9,12 @@ 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 functest.opnfv_tests.openstack.snaps.snaps_test_runner import \
+ SnapsTestRunner
from functest.utils.constants import CONST
-class ApiCheck(PyTestSuiteRunner):
+class ApiCheck(SnapsTestRunner):
"""
This test executes the Python Tests included with the SNAPS libraries
that exercise many of the OpenStack APIs within Keystone, Glance, Neutron,
@@ -25,10 +25,9 @@ class ApiCheck(PyTestSuiteRunner):
self.suite = unittest.TestSuite()
self.case_name = "api_check"
- ext_net_name = snaps_utils.get_ext_net_name()
test_suite_builder.add_openstack_api_tests(
self.suite,
CONST.openstack_creds,
- ext_net_name,
+ self.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 11f8ad074..0637bcfb3 100644
--- a/functest/opnfv_tests/openstack/snaps/connection_check.py
+++ b/functest/opnfv_tests/openstack/snaps/connection_check.py
@@ -9,12 +9,12 @@ 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 functest.opnfv_tests.openstack.snaps.snaps_test_runner import \
+ SnapsTestRunner
from functest.utils.constants import CONST
-class ConnectionCheck(PyTestSuiteRunner):
+class ConnectionCheck(SnapsTestRunner):
"""
This test executes the Python Tests included with the SNAPS libraries
that simply obtain the different OpenStack clients and may perform
@@ -25,10 +25,9 @@ class ConnectionCheck(PyTestSuiteRunner):
self.suite = unittest.TestSuite()
self.case_name = "connection_check"
- ext_net_name = snaps_utils.get_ext_net_name()
test_suite_builder.add_openstack_client_tests(
self.suite,
CONST.openstack_creds,
- ext_net_name,
+ self.ext_net_name,
use_keystone=CONST.snaps_use_keystone)
diff --git a/functest/opnfv_tests/openstack/snaps/health_check.py b/functest/opnfv_tests/openstack/snaps/health_check.py
index 993c1000c..8fece7465 100644
--- a/functest/opnfv_tests/openstack/snaps/health_check.py
+++ b/functest/opnfv_tests/openstack/snaps/health_check.py
@@ -7,15 +7,15 @@
import unittest
+from functest.opnfv_tests.openstack.snaps.snaps_test_runner import \
+ SnapsTestRunner
+from functest.utils.constants import CONST
+
from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
from snaps.openstack.tests.create_instance_tests import SimpleHealthCheck
-from functest.core.pytest_suite_runner import PyTestSuiteRunner
-from functest.opnfv_tests.openstack.snaps import snaps_utils
-from functest.utils.constants import CONST
-
-class HealthCheck(PyTestSuiteRunner):
+class HealthCheck(SnapsTestRunner):
"""
This test executes the SNAPS Python Test case SimpleHealthCheck which
creates a VM with a single port with an IPv4 address that is assigned by
@@ -26,9 +26,14 @@ class HealthCheck(PyTestSuiteRunner):
self.suite = unittest.TestSuite()
self.case_name = "snaps_health_check"
- ext_net_name = snaps_utils.get_ext_net_name()
+
+ image_custom_config = None
+ if hasattr(CONST, 'snaps_health_check'):
+ image_custom_config = CONST.snaps_health_check
self.suite.addTest(
OSIntegrationTestCase.parameterize(
- SimpleHealthCheck, CONST.openstack_creds, ext_net_name,
- use_keystone=CONST.snaps_use_keystone))
+ SimpleHealthCheck, CONST.openstack_creds, self.ext_net_name,
+ use_keystone=CONST.snaps_use_keystone,
+ flavor_metadata=self.flavor_metadata,
+ image_metadata=image_custom_config))
diff --git a/functest/opnfv_tests/openstack/snaps/smoke.py b/functest/opnfv_tests/openstack/snaps/smoke.py
index 83eb6600c..864bca5e6 100644
--- a/functest/opnfv_tests/openstack/snaps/smoke.py
+++ b/functest/opnfv_tests/openstack/snaps/smoke.py
@@ -10,12 +10,12 @@ 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 functest.opnfv_tests.openstack.snaps.snaps_test_runner import \
+ SnapsTestRunner
from functest.utils.constants import CONST
-class SnapsSmoke(PyTestSuiteRunner):
+class SnapsSmoke(SnapsTestRunner):
"""
This test executes the Python Tests included with the SNAPS libraries
that exercise many of the OpenStack APIs within Keystone, Glance, Neutron,
@@ -27,7 +27,12 @@ class SnapsSmoke(PyTestSuiteRunner):
self.suite = unittest.TestSuite()
self.case_name = "snaps_smoke"
use_fip = CONST.snaps_use_floating_ips
- ext_net_name = snaps_utils.get_ext_net_name()
+
+ # The snaps smoke test uses the same config as the
+ # snaps_health_check suite, so reuse it here
+ image_custom_config = None
+ if hasattr(CONST, 'snaps_health_check'):
+ image_custom_config = CONST.snaps_health_check
# Tests requiring floating IPs leverage files contained within the
# SNAPS repository and are found relative to that path
@@ -38,6 +43,7 @@ class SnapsSmoke(PyTestSuiteRunner):
test_suite_builder.add_openstack_integration_tests(
self.suite,
CONST.openstack_creds,
- ext_net_name,
+ self.ext_net_name,
use_keystone=CONST.snaps_use_keystone,
+ image_metadata=image_custom_config,
use_floating_ips=use_fip)
diff --git a/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py b/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py
new file mode 100644
index 000000000..67cd9415e
--- /dev/null
+++ b/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py
@@ -0,0 +1,30 @@
+# 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
+
+from functest.core.pytest_suite_runner import PyTestSuiteRunner
+from functest.opnfv_tests.openstack.snaps import snaps_utils
+from functest.utils import functest_utils
+
+from snaps.openstack import create_flavor
+
+
+class SnapsTestRunner(PyTestSuiteRunner):
+ """
+ This test executes the SNAPS Python Test case SimpleHealthCheck which
+ creates a VM with a single port with an IPv4 address that is assigned by
+ DHCP. This test then validates the expected IP with the actual
+ """
+ def __init__(self):
+ super(SnapsTestRunner, self).__init__()
+
+ self.ext_net_name = snaps_utils.get_ext_net_name()
+
+ scenario = functest_utils.get_scenario()
+
+ self.flavor_metadata = create_flavor.MEM_PAGE_SIZE_ANY
+ if 'ovs' in scenario or 'fdio' in scenario:
+ self.flavor_metadata = create_flavor.MEM_PAGE_SIZE_LARGE
diff --git a/functest/opnfv_tests/openstack/tempest/conf_utils.py b/functest/opnfv_tests/openstack/tempest/conf_utils.py
index 893fff8c2..2c113367b 100644
--- a/functest/opnfv_tests/openstack/tempest/conf_utils.py
+++ b/functest/opnfv_tests/openstack/tempest/conf_utils.py
@@ -106,6 +106,17 @@ def get_verifier_deployment_dir(verifier_id, deployment_id):
'for-deployment-{}'.format(deployment_id))
+def get_repo_tag(repo):
+ """
+ Returns last tag of current branch
+ """
+ cmd = ("git -C {0} describe --abbrev=0 HEAD".format(repo))
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
+ tag = p.stdout.readline().rstrip()
+
+ return str(tag)
+
+
def backup_tempest_config(conf_file):
"""
Copy config file to tempest results directory
@@ -276,3 +287,16 @@ def configure_tempest_multisite_params(tempest_conf_file):
config.write(config_file)
backup_tempest_config(tempest_conf_file)
+
+
+def install_verifier_ext(path):
+ """
+ Install extension to active verifier
+ """
+ logger.info("Installing verifier from existing repo...")
+ tag = get_repo_tag(path)
+ cmd = ("rally verify add-verifier-ext --source {0} "
+ "--version {1}"
+ .format(path, tag))
+ error_msg = ("Problem while adding verifier extension from %s" % path)
+ ft_utils.execute_command_raise(cmd, error_msg=error_msg)
diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
index 0a4256ce6..fcdfe225b 100644
--- a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
+++ b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
@@ -1,22 +1,3 @@
--
- scenarios:
- - os-odl_l2-bgpvpn-ha
- - os-odl_l2-bgpvpn-noha
- installers:
- - fuel
- - apex
- tests:
- - tempest.api.compute.servers.test_create_server.ServersTestJSON.test_list_servers
- - tempest.api.compute.servers.test_create_server.ServersTestJSON.test_verify_server_details
- - tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers
- - tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_server_details
- - tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_hard
- - tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_create_list_show_update_delete_floating_ip
- - tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_create_floating_ip_specifying_a_fixed_ip_address
- - tempest.scenario.test_network_basic_ops.TestNetworkBasicOps.test_network_basic_ops
- - tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops
- - tempest.scenario.test_volume_boot_pattern.TestVolumeBootPattern.test_volume_boot_pattern
- - tempest.scenario.test_volume_boot_pattern.TestVolumeBootPatternV2.test_volume_boot_pattern
-
scenarios:
diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py
index ae4eed09b..a6ce4ee6c 100644
--- a/functest/opnfv_tests/openstack/tempest/tempest.py
+++ b/functest/opnfv_tests/openstack/tempest/tempest.py
@@ -161,7 +161,8 @@ class TempestCommon(testcase_base.TestcaseBase):
result_file.close()
def run_verifier_tests(self):
- self.OPTION += (" --load-list {}".format(conf_utils.TEMPEST_LIST))
+ self.OPTION += (" --load-list {} --detailed"
+ .format(conf_utils.TEMPEST_LIST))
cmd_line = "rally verify start " + self.OPTION
logger.info("Starting Tempest test suite: '%s'." % cmd_line)
@@ -315,6 +316,7 @@ class TempestMultisite(TempestCommon):
self.case_name = "multisite"
self.MODE = "feature_multisite"
self.OPTION = "--concurrency 1"
+ conf_utils.install_verifier_ext(CONST.dir_repo_kingbird)
class TempestCustom(TempestCommon):
diff --git a/functest/opnfv_tests/sdn/odl/odl.py b/functest/opnfv_tests/sdn/odl/odl.py
index 69818f5a5..c8e9c4920 100755
--- a/functest/opnfv_tests/sdn/odl/odl.py
+++ b/functest/opnfv_tests/sdn/odl/odl.py
@@ -94,8 +94,11 @@ class ODLTests(testcase_base.TestcaseBase):
try:
odlusername = kwargs['odlusername']
odlpassword = kwargs['odlpassword']
- variables = ['KEYSTONE:' + kwargs['keystoneip'],
+ osauthurl = kwargs['osauthurl']
+ keystoneip = urlparse.urlparse(osauthurl).hostname
+ variables = ['KEYSTONE:' + keystoneip,
'NEUTRON:' + kwargs['neutronip'],
+ 'OS_AUTH_URL:"' + osauthurl + '"',
'OSUSERNAME:"' + kwargs['osusername'] + '"',
'OSTENANTNAME:"' + kwargs['ostenantname'] + '"',
'OSPASSWORD:"' + kwargs['ospassword'] + '"',
@@ -147,10 +150,8 @@ class ODLTests(testcase_base.TestcaseBase):
suites = kwargs["suites"]
except KeyError:
pass
- 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 = {'neutronip': urlparse.urlparse(neutron_url).hostname}
kwargs['odlip'] = kwargs['neutronip']
kwargs['odlwebport'] = '8080'
kwargs['odlrestconfport'] = '8181'
@@ -161,6 +162,7 @@ class ODLTests(testcase_base.TestcaseBase):
installer_type = os.environ['INSTALLER_TYPE']
kwargs['osusername'] = os.environ['OS_USERNAME']
kwargs['ostenantname'] = os.environ['OS_TENANT_NAME']
+ kwargs['osauthurl'] = os.environ['OS_AUTH_URL']
kwargs['ospassword'] = os.environ['OS_PASSWORD']
if installer_type == 'fuel':
kwargs['odlwebport'] = '8282'
@@ -191,12 +193,12 @@ class ODLParser(object):
def __init__(self):
self.parser = argparse.ArgumentParser()
self.parser.add_argument(
- '-k', '--keystoneip', help='Keystone IP',
- default='127.0.0.1')
- self.parser.add_argument(
'-n', '--neutronip', help='Neutron IP',
default='127.0.0.1')
self.parser.add_argument(
+ '-k', '--osauthurl', help='OS_AUTH_URL as defined by OpenStack',
+ default='http://127.0.0.1:5000/v2.0')
+ self.parser.add_argument(
'-a', '--osusername', help='Username for OpenStack',
default='admin')
self.parser.add_argument(
diff --git a/functest/opnfv_tests/sdn/onos/__init__.py b/functest/opnfv_tests/sdn/onos/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/opnfv_tests/sdn/onos/__init__.py
diff --git a/functest/opnfv_tests/sdn/onos/onos.py b/functest/opnfv_tests/sdn/onos/onos.py
new file mode 100644
index 000000000..8bc738325
--- /dev/null
+++ b/functest/opnfv_tests/sdn/onos/onos.py
@@ -0,0 +1,225 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 HUAWEI TECHNOLOGIES CO.,LTD and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import os
+import re
+import subprocess
+import shutil
+import time
+import urlparse
+
+from functest.core import 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 openstack_utils
+
+
+logger = ft_logger.Logger(__name__).getLogger()
+
+
+class OnosBase(testcase_base.TestcaseBase):
+ onos_repo_path = CONST.dir_repo_onos
+ onos_sfc_image_name = CONST.onos_sfc_image_name
+ onos_sfc_image_path = os.path.join(CONST.dir_functest_data,
+ CONST.onos_sfc_image_file_name)
+ onos_sfc_path = os.path.join(CONST.dir_repo_functest,
+ CONST.dir_onos_sfc)
+
+ def __init__(self):
+ super(OnosBase, self).__init__()
+
+ def run(self):
+ self.start_time = time.time()
+ try:
+ self._run()
+ res = testcase_base.TestcaseBase.EX_OK
+ except Exception as e:
+ logger.error('Error with run: %s', e)
+ res = testcase_base.TestcaseBase.EX_RUN_ERROR
+
+ self.stop_time = time.time()
+ return res
+
+ def _run(self):
+ raise NotImplementedError('_run is not implemented')
+
+
+class Onos(OnosBase):
+ def __init__(self):
+ super(Onos, self).__init__()
+ self.case_name = 'onos'
+ self.log_path = os.path.join(self.onos_repo_path, 'TestON/logs')
+
+ def set_onos_ip(self):
+ if (CONST.INSTALLER_TYPE and
+ CONST.INSTALLER_TYPE.lower() == 'joid'):
+ sdn_controller_env = os.getenv('SDN_CONTROLLER')
+ OC1 = re.search(r"\d+\.\d+\.\d+\.\d+", sdn_controller_env).group()
+ else:
+ neutron_url = openstack_utils.get_endpoint(service_type='network')
+ OC1 = urlparse.urlparse(neutron_url).hostname
+ os.environ['OC1'] = OC1
+ logger.debug("ONOS IP is %s" % OC1)
+
+ def run_onos_script(self, testname):
+ cli_dir = os.path.join(self.onos_repo_path, 'TestON/bin/cli.py')
+ cmd = '{0} run {1}'.format(cli_dir, testname)
+ logger.debug("Run script: %s" % testname)
+ ft_utils.execute_command_raise(
+ cmd,
+ error_msg=('Error when running ONOS script: %s'
+ % (testname)))
+
+ def clean_existing_logs(self):
+ log_dir = [f for f in os.listdir(self.log_path)]
+ for log in log_dir:
+ try:
+ if os.path.isdir(log):
+ shutil.rmtree(log)
+ elif os.path.isfile(log):
+ os.remove(log)
+ except OSError as e:
+ logger.error('Error with deleting file %s: %s',
+ log, e.strerror)
+
+ def get_result(self):
+ cmd = 'grep -rnh Fail {0}'.format(self.log_path)
+ p = subprocess.Popen(cmd,
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+
+ for line in p.stdout:
+ logger.debug(line)
+ if re.search("\s+[1-9]+\s+", line):
+ logger.debug("Testcase Fails\n" + line)
+
+ cmd = "grep -rnh 'Execution Time' {0}".format(self.log_path)
+ result_buffer = os.popen(cmd).read()
+ time1 = result_buffer[114:128]
+ time2 = result_buffer[28:42]
+ cmd = "grep -rnh 'Success Percentage' {0}".format(
+ os.path.join(self.log_path, "FUNCvirNetNB_*"))
+ result_buffer = os.popen(cmd).read()
+ if result_buffer.find('100%') >= 0:
+ result1 = 'Success'
+ else:
+ result1 = 'Failed'
+ cmd = "grep -rnh 'Success Percentage' {0}".format(
+ os.path.join(self.log_path, "FUNCvirNetNBL3*"))
+ result_buffer = os.popen(cmd).read()
+ if result_buffer.find('100%') >= 0:
+ result2 = 'Success'
+ else:
+ result2 = 'Failed'
+ status1 = []
+ status2 = []
+ cmd = "grep -rnh 'h3' {0}".format(
+ os.path.join(self.log_path, "FUNCvirNetNB_*"))
+ result_buffer = os.popen(cmd).read()
+ pattern = re.compile("<h3>([^-]+) - ([^-]+) - (\S*)</h3>")
+ # res = pattern.search(result_buffer).groups()
+ res = pattern.findall(result_buffer)
+ i = 0
+ for index in range(len(res)):
+ status1.append({'Case name:': res[i][0] + res[i][1],
+ 'Case result': res[i][2]})
+ i = i + 1
+ cmd = "grep -rnh 'h3' {0}".format(
+ os.path.join(self.log_path, "FUNCvirNetNBL3*"))
+ result_buffer = os.popen(cmd).read()
+ pattern = re.compile("<h3>([^-]+) - ([^-]+) - (\S*)</h3>")
+ res = pattern.findall(result_buffer)
+ i = 0
+ for index in range(len(res)):
+ status2.append({'Case name:': res[i][0] + res[i][1],
+ 'Case result': res[i][2]})
+ i = i + 1
+ payload = {'FUNCvirNet': {'duration': time1,
+ 'result': result1,
+ 'status': status1},
+ 'FUNCvirNetL3': {'duration': time2,
+ 'result': result2,
+ 'status': status2}}
+ return payload
+
+ def parse_result(self):
+ result = self.get_result()
+ status = "FAIL"
+ try:
+ if (result['FUNCvirNet']['result'] == "Success" and
+ result['FUNCvirNetL3']['result'] == "Success"):
+ status = "PASS"
+ except:
+ logger.error("Unable to set ONOS criteria")
+
+ self.criteria = status
+ self.details = result
+
+ def _run(self):
+ self.clean_existing_logs()
+ self.set_onos_ip()
+ self.run_onos_script('FUNCvirNetNB')
+ self.run_onos_script('FUNCvirNetNBL3')
+ self.parse_result()
+
+
+class OnosSfc(OnosBase):
+ def __init__(self):
+ super(OnosSfc, self).__init__()
+ self.case_name = 'onos_sfc'
+
+ def get_ip(type):
+ url = openstack_utils.get_endpoint(service_type=type)
+ logger.debug('get_ip for %s: %s' % (type, url))
+ return urlparse.urlparse(url).hostname
+
+ def update_sfc_onos_file(self, before, after):
+ file_dir = os.path.join(self.onos_sfc_path, "sfc_onos.py")
+ cmd = "sed -i 's/{0}/{1}/g' {2}".format(before,
+ after,
+ file_dir)
+ ft_utils.execute_command_raise(
+ cmd,
+ error_msg=('Error with replacing %s with %s'
+ % (before, after)))
+
+ def create_image(self):
+ glance_client = openstack_utils.get_glance_client()
+ image_id = openstack_utils.create_glance_image(
+ glance_client,
+ self.onos_sfc_image_name,
+ self.onos_sfc_image_path)
+ if image_id is None:
+ raise Exception('Failed to create image')
+
+ logger.debug("Image '%s' with ID=%s is created successfully."
+ % (self.onos_sfc_image_name, image_id))
+
+ def set_sfc_conf(self):
+ self.update_sfc_onos_file("keystone_ip", self.get_ip("keystone"))
+ self.update_sfc_onos_file("neutron_ip", self.get_ip("neutron"))
+ self.update_sfc_onos_file("nova_ip", self.get_ip("nova"))
+ self.update_sfc_onos_file("glance_ip", self.get_ip("glance"))
+ self.update_sfc_onos_file("console", CONST.OS_PASSWORD)
+ neutron_client = openstack_utils.get_neutron_client()
+ ext_net = openstack_utils.get_external_net(neutron_client)
+ self.update_sfc_onos_file("admin_floating_net", ext_net)
+ logger.debug("SFC configuration is modified")
+
+ def sfc_test(self):
+ cmd = 'python {0}'.format(os.path.join(self.onos_sfc_path, 'sfc.py'))
+ ft_utils.execute_command_raise(cmd,
+ error_msg='Error with testing SFC')
+
+ def _run(self):
+ self.create_image()
+ self.set_sfc_conf()
+ self.sfc_test()
diff --git a/functest/opnfv_tests/sdn/onos/teston/adapters/foundation.py b/functest/opnfv_tests/sdn/onos/teston/adapters/foundation.py
index 2bef5cc6e..25421d400 100644
--- a/functest/opnfv_tests/sdn/onos/teston/adapters/foundation.py
+++ b/functest/opnfv_tests/sdn/onos/teston/adapters/foundation.py
@@ -17,7 +17,7 @@ import os
import re
import time
-import functest.utils.functest_constants as ft_constants
+from functest.utils.constants import CONST
import functest.utils.functest_utils as ft_utils
@@ -26,7 +26,7 @@ class Foundation(object):
def __init__(self):
# currentpath = os.getcwd()
- currentpath = '%s/sdn/onos/teston/ci' % ft_constants.FUNCTEST_TEST_DIR
+ currentpath = '%s/sdn/onos/teston/ci' % CONST.dir_functest_data
self.cipath = currentpath
self.logdir = os.path.join(currentpath, 'log')
self.workhome = currentpath[0: currentpath.rfind('opnfv_tests') - 1]
@@ -54,23 +54,23 @@ class Foundation(object):
"""
Get Default Parameters value
"""
- self.Result_DB = str(ft_utils.get_db_url())
- self.masterusername = str(ft_constants.ONOSBENCH_USERNAME)
- self.masterpassword = str(ft_constants.ONOSBENCH_PASSWORD)
- self.agentusername = str(ft_constants.ONOSCLI_USERNAME)
- self.agentpassword = str(ft_constants.ONOSCLI_PASSWORD)
- self.runtimeout = ft_constants.ONOS_RUNTIMEOUT
- self.OCT = str(ft_constants.ONOS_OCT)
- self.OC1 = str(ft_constants.ONOS_OC1)
- self.OC2 = str(ft_constants.ONOS_OC2)
- self.OC3 = str(ft_constants.ONOS_OC3)
- self.OCN = str(ft_constants.ONOS_OCN)
- self.OCN2 = str(ft_constants.ONOS_OCN2)
- self.installer_master = str(ft_constants.ONOS_INSTALLER_MASTER)
- self.installer_master_username = \
- str(ft_constants.ONOS_INSTALLER_MASTER_USERNAME)
- self.installer_master_password = \
- ft_constants.ONOS_INSTALLER_MASTER_PASSWORD
+ self.Result_DB = ft_utils.get_db_url()
+ self.masterusername = CONST.ONOS_onosbench_username
+ self.masterpassword = CONST.ONOS_onosbench_password
+ self.agentusername = CONST.ONOS_onoscli_username
+ self.agentpassword = CONST.ONOS_onoscli_password
+ self.runtimeout = CONST.ONOS_runtimeout
+ self.OCT = CONST.ONOS_environment_OCT
+ self.OC1 = CONST.ONOS_environment_OC1
+ self.OC2 = CONST.ONOS_environment_OC2
+ self.OC3 = CONST.ONOS_environment_OC3
+ self.OCN = CONST.ONOS_environment_OCN
+ self.OCN2 = CONST.ONOS_environment_OCN2
+ self.installer_master = CONST.ONOS_environment_installer_master
+ self.installer_master_username = (
+ CONST.ONOS_environment_installer_master_username)
+ self.installer_master_password = (
+ CONST.ONOS_environment_installer_master_password)
self.hosts = [self.OC1, self.OCN, self.OCN2]
self.localhost = self.OCT
diff --git a/functest/opnfv_tests/sdn/onos/teston/onos.py b/functest/opnfv_tests/sdn/onos/teston/onos.py
deleted file mode 100755
index 2537e18de..000000000
--- a/functest/opnfv_tests/sdn/onos/teston/onos.py
+++ /dev/null
@@ -1,261 +0,0 @@
-"""
-Description: This test is to run onos Teston VTN scripts
-
-List of test cases:
-CASE1 - Northbound NBI test network/subnet/ports
-CASE2 - Ovsdb test&Default configuration&Vm go online
-
-lanqinglong@huawei.com
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-"""
-
-import datetime
-import os
-import re
-import time
-import urlparse
-
-import argparse
-from neutronclient.v2_0 import client as neutronclient
-
-import functest.utils.functest_constants as ft_constants
-import functest.utils.functest_logger as ft_logger
-import functest.utils.functest_utils as ft_utils
-import functest.utils.openstack_utils as openstack_utils
-
-
-parser = argparse.ArgumentParser()
-parser.add_argument("-t", "--testcase", help="Testcase name")
-args = parser.parse_args()
-
-
-""" logging configuration """
-logger = ft_logger.Logger("onos").getLogger()
-
-# onos parameters
-ONOSCI_PATH = ft_constants.REPOS_DIR + "/"
-starttime = datetime.datetime.now()
-
-INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
-ONOS_SFC_IMAGE_NAME = ft_constants.ONOS_SFC_IMAGE_NAME
-ONOS_SFC_IMAGE_PATH = os.path.join(ft_constants.FUNCTEST_DATA_DIR,
- ft_constants.ONOS_SFC_IMAGE_FILENAME)
-ONOS_SFC_PATH = os.path.join(ft_constants.FUNCTEST_REPO_DIR,
- ft_constants.ONOS_SFC_RELATIVE_PATH)
-
-
-def RunScript(testname):
- """
- Run ONOS Test Script
- Parameters:
- testname: ONOS Testcase Name
- """
- runtest = ONOSCI_PATH + "onos/TestON/bin/cli.py run " + testname
- logger.debug("Run script " + testname)
- os.system(runtest)
-
-
-def DownloadCodes(url="https://github.com/wuwenbin2/OnosSystemTest.git"):
- """
- Download Onos Teston codes
- Parameters:
- url: github url
- """
- downloadcode = "git clone " + url + " " + ONOSCI_PATH + "OnosSystemTest"
- logger.debug("Download Onos Teston codes " + url)
- os.system(downloadcode)
-
-
-def GetResult():
- LOGPATH = ONOSCI_PATH + "onos/TestON/logs"
- cmd = "grep -rnh " + "Fail" + " " + LOGPATH
- Resultbuffer = os.popen(cmd).read()
- # duration = datetime.datetime.now() - starttime
- time.sleep(2)
-
- if re.search("\s+[1-9]+\s+", Resultbuffer):
- logger.debug("Testcase Fails\n" + Resultbuffer)
- # Result = "Failed"
- else:
- logger.debug("Testcases Success")
- # Result = "Success"
- # payload={'timestart': str(starttime),
- # 'duration': str(duration),
- # 'status': Result}
- cmd = "grep -rnh 'Execution Time' " + LOGPATH
- Resultbuffer = os.popen(cmd).read()
- time1 = Resultbuffer[114:128]
- time2 = Resultbuffer[28:42]
- cmd = "grep -rnh 'Success Percentage' " + LOGPATH + "/FUNCvirNetNB_*"
- Resultbuffer = os.popen(cmd).read()
- if Resultbuffer.find('100%') >= 0:
- result1 = 'Success'
- else:
- result1 = 'Failed'
- cmd = "grep -rnh 'Success Percentage' " + LOGPATH + "/FUNCvirNetNBL3*"
- Resultbuffer = os.popen(cmd).read()
- if Resultbuffer.find('100%') >= 0:
- result2 = 'Success'
- else:
- result2 = 'Failed'
- status1 = []
- status2 = []
- cmd = "grep -rnh 'h3' " + LOGPATH + "/FUNCvirNetNB_*"
- Resultbuffer = os.popen(cmd).read()
- pattern = re.compile("<h3>([^-]+) - ([^-]+) - (\S*)</h3>")
- # res = pattern.search(Resultbuffer).groups()
- res = pattern.findall(Resultbuffer)
- i = 0
- for index in range(len(res)):
- status1.append({'Case name:': res[i][0] + res[i][1],
- 'Case result': res[i][2]})
- i = i + 1
- cmd = "grep -rnh 'h3' " + LOGPATH + "/FUNCvirNetNBL3*"
- Resultbuffer = os.popen(cmd).read()
- pattern = re.compile("<h3>([^-]+) - ([^-]+) - (\S*)</h3>")
- # res = pattern.search(Resultbuffer).groups()
- res = pattern.findall(Resultbuffer)
- i = 0
- for index in range(len(res)):
- status2.append({'Case name:': res[i][0] + res[i][1],
- 'Case result': res[i][2]})
- i = i + 1
- payload = {'timestart': str(starttime),
- 'FUNCvirNet': {'duration': time1,
- 'result': result1,
- 'status': status1},
- 'FUNCvirNetL3': {'duration': time2,
- 'result': result2,
- 'status': status2}}
- return payload
-
-
-def SetOnosIp():
- # cmd = "openstack catalog show network | grep publicURL"
- neutron_url = openstack_utils.get_endpoint(service_type='network')
- OC1 = urlparse.urlparse(neutron_url).hostname
- os.environ['OC1'] = OC1
- time.sleep(2)
- logger.debug("ONOS IP is " + OC1)
-
-
-def SetOnosIpForJoid():
- cmd = "env | grep SDN_CONTROLLER"
- cmd_output = os.popen(cmd).read()
- OC1 = re.search(r"\d+\.\d+\.\d+\.\d+", cmd_output).group()
- os.environ['OC1'] = OC1
- time.sleep(2)
- logger.debug("ONOS IP is " + OC1)
-
-
-def CleanOnosTest():
- TESTONPATH = ONOSCI_PATH + "onos/"
- cmd = "rm -rf " + TESTONPATH
- os.system(cmd)
- time.sleep(2)
- logger.debug("Clean ONOS Teston")
-
-
-def CreateImage():
- glance_client = openstack_utils.get_glance_client()
- image_id = openstack_utils.create_glance_image(glance_client,
- ONOS_SFC_IMAGE_NAME,
- ONOS_SFC_IMAGE_PATH)
- EXIT_CODE = -1
- if not image_id:
- logger.error("Failed to create a Glance image...")
- return(EXIT_CODE)
- logger.debug("Image '%s' with ID=%s created successfully."
- % (ONOS_SFC_IMAGE_NAME, image_id))
-
-
-def SfcTest():
- cmd = "python " + ONOS_SFC_PATH + "/sfc.py"
- logger.debug("Run sfc tests")
- os.system(cmd)
-
-
-def GetIp(type):
- # cmd = "openstack catalog show " + type + " | grep publicURL"
- url = openstack_utils.get_endpoint(service_type=type)
- return urlparse.urlparse(url).hostname
-
-
-def Replace(before, after):
- file = "/sfc_onos.py"
- cmd = "sed -i 's/" + before + "/" + after + "/g' " + ONOS_SFC_PATH + file
- os.system(cmd)
-
-
-def SetSfcConf():
- Replace("keystone_ip", GetIp("keystone"))
- Replace("neutron_ip", GetIp("neutron"))
- Replace("nova_ip", GetIp("nova"))
- Replace("glance_ip", GetIp("glance"))
- pwd = ft_constants.OS_PASSWORD
- Replace("console", pwd)
- creds_neutron = openstack_utils.get_credentials()
- neutron_client = neutronclient.Client(**creds_neutron)
- ext_net = openstack_utils.get_external_net(neutron_client)
- Replace("admin_floating_net", ext_net)
- logger.info("Modify configuration for SFC")
-
-
-def OnosTest():
- start_time = time.time()
- stop_time = start_time
- if INSTALLER_TYPE == "joid":
- logger.debug("Installer is Joid")
- SetOnosIpForJoid()
- else:
- SetOnosIp()
- RunScript("FUNCvirNetNB")
- RunScript("FUNCvirNetNBL3")
- try:
- logger.debug("Push ONOS results into DB")
- # TODO check path result for the file
- result = GetResult()
- stop_time = time.time()
-
- # ONOS success criteria = all tests OK
- # i.e. FUNCvirNet & FUNCvirNetL3
- status = "FAIL"
- try:
- if (result['FUNCvirNet']['result'] == "Success" and
- result['FUNCvirNetL3']['result'] == "Success"):
- status = "PASS"
- except:
- logger.error("Unable to set ONOS criteria")
-
- ft_utils.push_results_to_db("functest",
- "onos",
- start_time,
- stop_time,
- status,
- result)
-
- except:
- logger.error("Error pushing results into Database")
-
- if status == "FAIL":
- EXIT_CODE = -1
- exit(EXIT_CODE)
-
-
-def main():
-
- if args.testcase == "sfc":
- CreateImage()
- SetSfcConf()
- SfcTest()
- else:
- OnosTest()
-
-
-if __name__ == '__main__':
- main()
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
index c2c251ad2..e2401d0f1 100644
--- a/functest/opnfv_tests/vnf/ims/cloudify_ims.py
+++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
@@ -234,7 +234,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
cw.set_external_network_name(ext_net)
- error = cw.deploy_vnf()
+ error = cw.deploy_vnf(self.vnf['blueprint'])
if error:
self.logger.error(error)
return {'status': 'FAIL', 'result': error}
diff --git a/functest/opnfv_tests/vnf/ims/orchestra_ims.py b/functest/opnfv_tests/vnf/ims/orchestra_ims.py
index 352b609b0..42b218e62 100644
--- a/functest/opnfv_tests/vnf/ims/orchestra_ims.py
+++ b/functest/opnfv_tests/vnf/ims/orchestra_ims.py
@@ -23,6 +23,45 @@ from functest.utils.constants import CONST
from org.openbaton.cli.agents.agents import MainAgent
from org.openbaton.cli.errors.errors import NfvoException
+# ----------------------------------------------------------
+#
+# UTILS
+#
+# -----------------------------------------------------------
+
+
+def get_config(parameter, file):
+ """
+ Returns the value of a given parameter in file.yaml
+ parameter must be given in string format with dots
+ Example: general.openstack.image_name
+ """
+ with open(file) as f:
+ file_yaml = yaml.safe_load(f)
+ f.close()
+ value = file_yaml
+ for element in parameter.split("."):
+ value = value.get(element)
+ if value is None:
+ raise ValueError("The parameter %s is not defined in"
+ " %s" % (parameter, file))
+ return value
+
+
+def download_and_add_image_on_glance(glance, image_name,
+ image_url, data_dir):
+ dest_path = data_dir
+ if not os.path.exists(dest_path):
+ os.makedirs(dest_path)
+ file_name = image_url.rsplit('/')[-1]
+ if not ft_utils.download_url(image_url, dest_path):
+ return False
+ image = os_utils.create_glance_image(
+ glance, image_name, dest_path + file_name)
+ if not image:
+ return False
+ return image
+
def servertest(host, port):
args = socket.getaddrinfo(host, port, socket.AF_INET, socket.SOCK_STREAM)
@@ -38,6 +77,7 @@ def servertest(host, port):
class ImsVnf(vnf_base.VnfOnBoardingBase):
+
def __init__(self, project='functest', case='orchestra_ims',
repo='', cmd=''):
super(ImsVnf, self).__init__(project, case, repo, cmd)
@@ -54,6 +94,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
self.ob_projectid = ""
self.keystone_client = os_utils.get_keystone_client()
self.ob_nsr_id = ""
+ self.nsr = None
self.main_agent = None
# vIMS Data directory creation
if not os.path.exists(self.data_dir):
@@ -66,9 +107,14 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
raise Exception("Orchestra VNF config file not found")
config_file = self.case_dir + self.config
self.imagename = get_config("openbaton.imagename", config_file)
+ self.bootstrap_link = get_config("openbaton.bootstrap_link",
+ config_file)
+ self.bootstrap_config_link = get_config(
+ "openbaton.bootstrap_config_link", config_file)
self.market_link = get_config("openbaton.marketplace_link",
config_file)
self.images = get_config("tenant_images", config_file)
+ self.ims_conf = get_config("vIMS", config_file)
def deploy_orchestrator(self, **kwargs):
self.logger.info("Additional pre-configuration steps")
@@ -77,6 +123,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
glance_client = os_utils.get_glance_client()
# Import images if needed
+ # needs some images
self.logger.info("Upload some OS images if it doesn't exist")
temp_dir = os.path.join(self.data_dir, "tmp/")
for image_name, image_url in self.images.iteritems():
@@ -106,9 +153,9 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
"192.168.100.0/24")
# orchestrator VM flavor
- self.logger.info("Check medium Flavor is available, if not create one")
+ self.logger.info("Check if Flavor is available, if not create one")
flavor_exist, flavor_id = os_utils.get_or_create_flavor(
- "m1.medium",
+ "orchestra",
"4096",
'20',
'2',
@@ -129,13 +176,14 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
self.logger.error("Cannot create floating IP.")
userdata = "#!/bin/bash\n"
+ userdata += "echo \"Executing userdata...\"\n"
userdata += "set -x\n"
userdata += "set -e\n"
+ userdata += "echo \"Set nameserver to '8.8.8.8'...\"\n"
userdata += "echo \"nameserver 8.8.8.8\" >> /etc/resolv.conf\n"
+ userdata += "echo \"Install curl...\"\n"
userdata += "apt-get install curl\n"
- userdata += ("echo \"rabbitmq_broker_ip=%s\" > ./config_file\n"
- % floatip)
- userdata += "echo \"mysql=no\" >> ./config_file\n"
+ userdata += "echo \"Inject public key...\"\n"
userdata += ("echo \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuPXrV3"
"geeHc6QUdyUr/1Z+yQiqLcOskiEGBiXr4z76MK4abiFmDZ18OMQlc"
"fl0p3kS0WynVgyaOHwZkgy/DIoIplONVr2CKBKHtPK+Qcme2PVnCtv"
@@ -145,17 +193,30 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
"7YAdalAnyD/jwCHuwIrUw/lxo7UdNCmaUxeobEYyyFA1YVXzpNFZya"
"XPGAAYIJwEq/ openbaton@opnfv\" >> /home/ubuntu/.ssh/aut"
"horized_keys\n")
- userdata += "cat ./config_file\n"
- userdata += ("curl -s http://get.openbaton.org/bootstrap "
- "> ./bootstrap\n")
+ userdata += "echo \"Download bootstrap...\"\n"
+ userdata += ("curl -s %s "
+ "> ./bootstrap\n" % self.bootstrap_link)
+ userdata += ("curl -s %s"
+ "> ./config_file\n" % self.bootstrap_config_link)
+ userdata += ("echo \"Disable usage of mysql...\"\n")
+ userdata += "sed -i s/mysql=.*/mysql=no/g /config_file\n"
+ userdata += ("echo \"Setting 'rabbitmq_broker_ip' to '%s'\"\n"
+ % floatip)
+ userdata += ("sed -i s/rabbitmq_broker_ip=localhost/rabbitmq_broker_ip"
+ "=%s/g /config_file\n" % floatip)
+ userdata += "echo \"Set autostart of components to 'false'\"\n"
userdata += "export OPENBATON_COMPONENT_AUTOSTART=false\n"
+ userdata += "echo \"Execute bootstrap...\"\n"
bootstrap = "sh ./bootstrap release -configFile=./config_file"
userdata += bootstrap + "\n"
-
+ userdata += "echo \"Setting 'nfvo.plugin.timeout' to '300000'\"\n"
userdata += ("echo \"nfvo.plugin.timeout=300000\" >> "
"/etc/openbaton/openbaton-nfvo.properties\n")
+ userdata += "echo \"Starting NFVO\"\n"
userdata += "service openbaton-nfvo restart\n"
+ userdata += "echo \"Starting Generic VNFM\"\n"
userdata += "service openbaton-vnfm-generic restart\n"
+ userdata += "echo \"...end of userdata...\"\n"
sg_id = os_utils.create_security_group_full(neutron_client,
"orchestra-sec-group",
@@ -200,22 +261,22 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
self.logger.info("Associating floating ip: '%s' to VM '%s' "
% (floatip, "orchestra-openbaton"))
if not os_utils.add_floating_ip(nova_client, instance.id, floatip):
- self.logger.error("Cannot associate floating IP to VM.")
self.step_failure("Cannot associate floating IP to VM.")
- self.logger.info("Waiting for nfvo to be up and running...")
+ self.logger.info("Waiting for Open Baton NFVO to be up and running...")
x = 0
while x < 100:
if servertest(floatip, "8080"):
break
else:
- self.logger.debug("openbaton is not started yet")
+ self.logger.debug(
+ "Open Baton NFVO is not started yet (%ss)" %
+ (x * 5))
time.sleep(5)
x += 1
if x == 100:
- self.logger.error("Openbaton is not started correctly")
- self.step_failure("Openbaton is not started correctly")
+ self.step_failure("Open Baton is not started correctly")
self.ob_ip = floatip
self.ob_password = "openbaton"
@@ -223,10 +284,10 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
self.ob_https = False
self.ob_port = "8080"
- self.logger.info("Deploy orchestrator: OK")
+ self.logger.info("Deploy Open Baton NFVO: OK")
def deploy_vnf(self):
- self.logger.info("vIMS Deployment")
+ self.logger.info("Starting vIMS Deployment...")
self.main_agent = MainAgent(nfvo_ip=self.ob_ip,
nfvo_port=self.ob_port,
@@ -235,15 +296,16 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
username=self.ob_username,
password=self.ob_password)
+ self.logger.info("Getting project 'default'...")
project_agent = self.main_agent.get_agent("project", self.ob_projectid)
for p in json.loads(project_agent.find()):
if p.get("name") == "default":
self.ob_projectid = p.get("id")
+ self.logger.info("Found project 'default': %s" % p)
break
self.logger.debug("project id: %s" % self.ob_projectid)
if self.ob_projectid == "":
- self.logger.error("Default project id was not found!")
self.step_failure("Default project id was not found!")
vim_json = {
@@ -252,9 +314,6 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
"tenant": os_utils.get_credentials().get("tenant_name"),
"username": os_utils.get_credentials().get("username"),
"password": os_utils.get_credentials().get("password"),
- "keyPair": "opnfv",
- # TODO change the keypair to correct value
- # or upload a correct one or remove it
"securityGroups": [
"default",
"orchestra-sec-group"
@@ -267,7 +326,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
}
}
- self.logger.debug("vim: %s" % vim_json)
+ self.logger.debug("Registering VIM: %s" % vim_json)
self.main_agent.get_agent(
"vim",
@@ -280,7 +339,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
try:
self.logger.info("sending: %s" % self.market_link)
nsd = market_agent.create(entity=self.market_link)
- self.logger.info("Onboarded nsd: " + nsd.get("name"))
+ self.logger.info("Onboarded NSD: " + nsd.get("name"))
except NfvoException as e:
self.step_failure(e.message)
@@ -290,34 +349,77 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
if nsd_id is None:
self.step_failure("NSD not onboarded correctly")
- nsr = None
try:
- nsr = nsr_agent.create(nsd_id)
+ self.nsr = nsr_agent.create(nsd_id)
except NfvoException as e:
self.step_failure(e.message)
- if nsr is None:
- self.step_failure("NSR not deployed correctly")
+ if self.nsr.get('code') is not None:
+ self.logger.error(
+ "vIMS cannot be deployed: %s -> %s" %
+ (self.nsr.get('code'), self.nsr.get('message')))
+ self.step_failure("vIMS cannot be deployed")
i = 0
- self.logger.info("waiting NSR to go to active...")
- while nsr.get("status") != 'ACTIVE':
+ self.logger.info("Waiting for NSR to go to ACTIVE...")
+ while self.nsr.get("status") != 'ACTIVE' and self.nsr.get(
+ "status") != 'ERROR':
i += 1
- if i == 100:
- self.step_failure("After %s sec the nsr did not go to active.."
- % 5 * 100)
+ if i == 150:
+ self.step_failure("After %s sec the NSR did not go to ACTIVE.."
+ % 5 * i)
time.sleep(5)
- nsr = json.loads(nsr_agent.find(nsr.get('id')))
+ self.nsr = json.loads(nsr_agent.find(self.nsr.get('id')))
- deploy_vnf = {'status': "PASS", 'result': nsr}
- self.ob_nsr_id = nsr.get("id")
- self.logger.info("Deploy VNF: OK")
+ if self.nsr.get("status") == 'ACTIVE':
+ deploy_vnf = {'status': "PASS", 'result': self.nsr}
+ self.logger.info("Deploy VNF: OK")
+ else:
+ deploy_vnf = {'status': "FAIL", 'result': self.nsr}
+ self.step_failure("Deploy VNF: ERROR")
+ self.ob_nsr_id = self.nsr.get("id")
+ self.logger.info(
+ "Sleep for 60s to ensure that all services are up and running...")
+ time.sleep(60)
return deploy_vnf
def test_vnf(self):
# Adaptations probably needed
# code used for cloudify_ims
# ruby client on jumphost calling the vIMS on the SUT
+ self.logger.info(
+ "Testing if %s works properly..." %
+ self.nsr.get('name'))
+ for vnfr in self.nsr.get('vnfr'):
+ self.logger.info(
+ "Checking ports %s of VNF %s" %
+ (self.ims_conf.get(
+ vnfr.get('name')).get('ports'),
+ vnfr.get('name')))
+ for vdu in vnfr.get('vdu'):
+ for vnfci in vdu.get('vnfc_instance'):
+ self.logger.debug(
+ "Checking ports of VNFC instance %s" %
+ vnfci.get('hostname'))
+ for floatingIp in vnfci.get('floatingIps'):
+ self.logger.debug(
+ "Testing %s:%s" %
+ (vnfci.get('hostname'), floatingIp.get('ip')))
+ for port in self.ims_conf.get(
+ vnfr.get('name')).get('ports'):
+ if servertest(floatingIp.get('ip'), port):
+ self.logger.info(
+ "VNFC instance %s is reachable at %s:%s" %
+ (vnfci.get('hostname'),
+ floatingIp.get('ip'),
+ port))
+ else:
+ self.logger.error(
+ "VNFC instance %s is not reachable "
+ "at %s:%s" % (vnfci.get('hostname'),
+ floatingIp.get('ip'), port))
+ self.step_failure("Test VNF: ERROR")
+ self.logger.info("Test VNF: OK")
return
def clean(self):
@@ -349,42 +451,5 @@ if __name__ == '__main__':
test = ImsVnf()
test.deploy_orchestrator()
test.deploy_vnf()
+ test.test_vnf()
test.clean()
-
-
-# ----------------------------------------------------------
-#
-# UTILS
-#
-# -----------------------------------------------------------
-def get_config(parameter, file):
- """
- Returns the value of a given parameter in file.yaml
- parameter must be given in string format with dots
- Example: general.openstack.image_name
- """
- with open(file) as f:
- file_yaml = yaml.safe_load(f)
- f.close()
- value = file_yaml
- for element in parameter.split("."):
- value = value.get(element)
- if value is None:
- raise ValueError("The parameter %s is not defined in"
- " reporting.yaml" % parameter)
- return value
-
-
-def download_and_add_image_on_glance(glance, image_name,
- image_url, data_dir):
- dest_path = data_dir
- if not os.path.exists(dest_path):
- os.makedirs(dest_path)
- file_name = image_url.rsplit('/')[-1]
- if not ft_utils.download_url(image_url, dest_path):
- return False
- image = os_utils.create_glance_image(
- glance, image_name, dest_path + file_name)
- if not image:
- return False
- return image
diff --git a/functest/opnfv_tests/vnf/ims/orchestra_ims.yaml b/functest/opnfv_tests/vnf/ims/orchestra_ims.yaml
index 2fb33df5d..86d6e604a 100644
--- a/functest/opnfv_tests/vnf/ims/orchestra_ims.yaml
+++ b/functest/opnfv_tests/vnf/ims/orchestra_ims.yaml
@@ -2,6 +2,18 @@ tenant_images:
ubuntu_14.04: http://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img
openims: http://marketplace.openbaton.org:8082/api/v1/images/52e2ccc0-1dce-4663-894d-28aab49323aa/img
openbaton:
- bootstrap: sh <(curl -s http://get.openbaton.org/bootstrap) release -configFile=
+ bootstrap_link: http://get.openbaton.org/bootstrap
+ bootstrap_config_link: http://get.openbaton.org/bootstrap-config-file
marketplace_link: http://marketplace.openbaton.org:8082/api/v1/nsds/fokus/OpenImsCore/3.2.0/json
imagename: ubuntu_14.04
+vIMS:
+ scscf:
+ ports: [3870, 6060]
+ pcscf:
+ ports: [4060]
+ icscf:
+ ports: [3869, 5060]
+ fhoss:
+ ports: [3868]
+ bind9:
+ ports: [] \ No newline at end of file
diff --git a/functest/tests/unit/ci/__init__.py b/functest/tests/unit/ci/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/tests/unit/ci/__init__.py
diff --git a/functest/tests/unit/ci/test_prepare_env.py b/functest/tests/unit/ci/test_prepare_env.py
new file mode 100644
index 000000000..540501ff0
--- /dev/null
+++ b/functest/tests/unit/ci/test_prepare_env.py
@@ -0,0 +1,347 @@
+#!/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.ci import prepare_env
+from functest.tests.unit import test_utils
+from functest.utils.constants import CONST
+from opnfv.utils import constants as opnfv_constants
+
+
+class PrepareEnvTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ def test_print_separator(self, mock_logger_info):
+ str = "=============================================="
+ prepare_env.print_separator()
+ mock_logger_info.assert_called_once_with(str)
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.warning')
+ def test_check_env_variables_missing_inst_type(self, mock_logger_warn,
+ mock_logger_info):
+ CONST.INSTALLER_TYPE = None
+ prepare_env.check_env_variables()
+ mock_logger_info.assert_any_call("Checking environment variables"
+ "...")
+ mock_logger_warn.assert_any_call("The env variable 'INSTALLER_TYPE'"
+ " is not defined.")
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.warning')
+ def test_check_env_variables_missing_inst_ip(self, mock_logger_warn,
+ mock_logger_info):
+ CONST.INSTALLER_IP = None
+ prepare_env.check_env_variables()
+ mock_logger_info.assert_any_call("Checking environment variables"
+ "...")
+ mock_logger_warn.assert_any_call("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.")
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.warning')
+ def test_check_env_variables_with_inst_ip(self, mock_logger_warn,
+ mock_logger_info):
+ CONST.INSTALLER_IP = mock.Mock()
+ prepare_env.check_env_variables()
+ mock_logger_info.assert_any_call("Checking environment variables"
+ "...")
+ mock_logger_info.assert_any_call(test_utils.
+ SubstrMatch(" INSTALLER_IP="))
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.warning')
+ def test_check_env_variables_missing_scenario(self, mock_logger_warn,
+ mock_logger_info):
+ CONST.DEPLOY_SCENARIO = None
+ prepare_env.check_env_variables()
+ mock_logger_info.assert_any_call("Checking environment variables"
+ "...")
+ mock_logger_warn.assert_any_call("The env variable"
+ " 'DEPLOY_SCENARIO' is not defined"
+ ". Setting CI_SCENARIO=undefined.")
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.warning')
+ def test_check_env_variables_with_scenario(self, mock_logger_warn,
+ mock_logger_info):
+ CONST.DEPLOY_SCENARIO = mock.Mock()
+ prepare_env.check_env_variables()
+ mock_logger_info.assert_any_call("Checking environment variables"
+ "...")
+ mock_logger_info.assert_any_call(test_utils.
+ SubstrMatch("DEPLOY_SCENARIO="))
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.warning')
+ def test_check_env_variables_with_ci_debug(self, mock_logger_warn,
+ mock_logger_info):
+ CONST.CI_DEBUG = mock.Mock()
+ prepare_env.check_env_variables()
+ mock_logger_info.assert_any_call("Checking environment variables"
+ "...")
+ mock_logger_info.assert_any_call(test_utils.
+ SubstrMatch(" CI_DEBUG="))
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.warning')
+ def test_check_env_variables_with_node(self, mock_logger_warn,
+ mock_logger_info):
+ CONST.NODE_NAME = mock.Mock()
+ prepare_env.check_env_variables()
+ mock_logger_info.assert_any_call("Checking environment variables"
+ "...")
+ mock_logger_info.assert_any_call(test_utils.
+ SubstrMatch(" NODE_NAME="))
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.warning')
+ def test_check_env_variables_with_build_tag(self, mock_logger_warn,
+ mock_logger_info):
+ CONST.BUILD_TAG = mock.Mock()
+ prepare_env.check_env_variables()
+ mock_logger_info.assert_any_call("Checking environment variables"
+ "...")
+
+ mock_logger_info.assert_any_call(test_utils.
+ SubstrMatch(" BUILD_TAG="))
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.warning')
+ def test_check_env_variables_with_is_ci_run(self, mock_logger_warn,
+ mock_logger_info):
+ CONST.IS_CI_RUN = mock.Mock()
+ prepare_env.check_env_variables()
+ mock_logger_info.assert_any_call("Checking environment variables"
+ "...")
+
+ mock_logger_info.assert_any_call(test_utils.
+ SubstrMatch(" IS_CI_RUN="))
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.debug')
+ def test_create_directories_missing_dir(self, mock_logger_debug,
+ mock_logger_info):
+ with mock.patch('functest.ci.prepare_env.os.path.exists',
+ return_value=False), \
+ mock.patch('functest.ci.prepare_env.os.makedirs') \
+ as mock_method:
+ prepare_env.create_directories()
+ mock_logger_info.assert_any_call("Creating needed directories...")
+ mock_method.assert_any_call(CONST.dir_functest_conf)
+ mock_method.assert_any_call(CONST.dir_functest_data)
+ mock_logger_info.assert_any_call(" %s created." %
+ CONST.dir_functest_conf)
+ mock_logger_info.assert_any_call(" %s created." %
+ CONST.dir_functest_data)
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.debug')
+ def test_create_directories_with_dir(self, mock_logger_debug,
+ mock_logger_info):
+ with mock.patch('functest.ci.prepare_env.os.path.exists',
+ return_value=True):
+ prepare_env.create_directories()
+ mock_logger_info.assert_any_call("Creating needed directories...")
+ mock_logger_debug.assert_any_call(" %s already exists." %
+ CONST.dir_functest_conf)
+ mock_logger_debug.assert_any_call(" %s already exists." %
+ CONST.dir_functest_data)
+
+ def _get_env_cred_dict(self, os_prefix=''):
+ return {'OS_USERNAME': os_prefix + 'username',
+ 'OS_PASSWORD': os_prefix + 'password',
+ 'OS_AUTH_URL': 'http://test_ip:test_port/v2.0',
+ 'OS_TENANT_NAME': os_prefix + 'tenant_name',
+ 'OS_USER_DOMAIN_NAME': os_prefix + 'user_domain_name',
+ 'OS_PROJECT_DOMAIN_NAME': os_prefix + 'project_domain_name',
+ 'OS_PROJECT_NAME': os_prefix + 'project_name',
+ 'OS_ENDPOINT_TYPE': os_prefix + 'endpoint_type',
+ 'OS_REGION_NAME': os_prefix + 'region_name'}
+
+ @mock.patch('functest.ci.prepare_env.logger.error')
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.logger.warning')
+ def test_source_rc_missing_rc_file(self, mock_logger_warn,
+ mock_logger_info,
+ mock_logger_error):
+ with mock.patch('functest.ci.prepare_env.os.path.isfile',
+ return_value=True), \
+ mock.patch('functest.ci.prepare_env.os.path.getsize',
+ return_value=0), \
+ self.assertRaises(Exception):
+ CONST.openstack_creds = 'test_creds'
+ prepare_env.source_rc_file()
+
+ def test_source_rc_missing_installer_ip(self):
+ with mock.patch('functest.ci.prepare_env.os.path.isfile',
+ return_value=False), \
+ self.assertRaises(Exception):
+ CONST.INSTALLER_IP = None
+ CONST.openstack_creds = 'test_creds'
+ prepare_env.source_rc_file()
+
+ def test_source_rc_missing_installer_type(self):
+ with mock.patch('functest.ci.prepare_env.os.path.isfile',
+ return_value=False), \
+ self.assertRaises(Exception):
+ CONST.INSTALLER_IP = 'test_ip'
+ CONST.openstack_creds = 'test_creds'
+ CONST.INSTALLER_TYPE = 'test_type'
+ opnfv_constants.INSTALLERS = []
+ prepare_env.source_rc_file()
+
+ def test_source_rc_missing_os_credfile_ci_inst(self):
+ with mock.patch('functest.ci.prepare_env.os.path.isfile',
+ return_value=False), \
+ mock.patch('functest.ci.prepare_env.os.path.getsize'), \
+ mock.patch('functest.ci.prepare_env.os.path.join'), \
+ mock.patch('functest.ci.prepare_env.subprocess.Popen') \
+ as mock_subproc_popen, \
+ self.assertRaises(Exception):
+ CONST.openstack_creds = 'test_creds'
+ CONST.INSTALLER_IP = None
+ CONST.INSTALLER_TYPE = 'test_type'
+ opnfv_constants.INSTALLERS = ['test_type']
+
+ process_mock = mock.Mock()
+ attrs = {'communicate.return_value': ('output', 'error'),
+ 'return_code': 1}
+ process_mock.configure_mock(**attrs)
+ mock_subproc_popen.return_value = process_mock
+
+ prepare_env.source_rc_file()
+
+ def _get_rally_creds(self):
+ return {"type": "ExistingCloud",
+ "admin": {"username": 'test_user_name',
+ "password": 'test_password',
+ "tenant": 'test_tenant'}}
+
+ @mock.patch('functest.ci.prepare_env.os_utils.get_credentials_for_rally')
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ @mock.patch('functest.ci.prepare_env.ft_utils.execute_command_raise')
+ @mock.patch('functest.ci.prepare_env.ft_utils.execute_command')
+ def test_install_rally(self, mock_exec, mock_exec_raise, mock_logger_info,
+ mock_os_utils):
+
+ mock_os_utils.return_value = self._get_rally_creds()
+
+ prepare_env.install_rally()
+
+ cmd = "rally deployment destroy opnfv-rally"
+ error_msg = "Deployment %s does not exist." % \
+ CONST.rally_deployment_name
+ mock_logger_info.assert_any_call("Creating Rally environment...")
+ mock_exec.assert_any_call(cmd, error_msg=error_msg, verbose=False)
+
+ cmd = "rally deployment create --file=rally_conf.json --name="
+ cmd += CONST.rally_deployment_name
+ error_msg = "Problem while creating Rally deployment"
+ mock_exec_raise.assert_any_call(cmd, error_msg=error_msg)
+
+ cmd = "rally deployment check"
+ error_msg = ("OpenStack not responding or "
+ "faulty Rally deployment.")
+ mock_exec_raise.assert_any_call(cmd, error_msg=error_msg)
+
+ cmd = "rally deployment list"
+ error_msg = ("Problem while listing "
+ "Rally deployment.")
+ mock_exec.assert_any_call(cmd, error_msg=error_msg)
+
+ cmd = "rally plugin list | head -5"
+ error_msg = ("Problem while showing "
+ "Rally plugins.")
+ mock_exec.assert_any_call(cmd, error_msg=error_msg)
+
+ @mock.patch('functest.ci.prepare_env.sys.exit')
+ @mock.patch('functest.ci.prepare_env.logger.error')
+ def test_check_environment_missing_file(self, mock_logger_error,
+ mock_sys_exit):
+ with mock.patch('functest.ci.prepare_env.os.path.isfile',
+ return_value=False), \
+ self.assertRaises(Exception):
+ prepare_env.check_environment()
+
+ @mock.patch('functest.ci.prepare_env.sys.exit')
+ @mock.patch('functest.ci.prepare_env.logger.error')
+ def test_check_environment_with_error(self, mock_logger_error,
+ mock_sys_exit):
+ with mock.patch('functest.ci.prepare_env.os.path.isfile',
+ return_value=True), \
+ mock.patch("__builtin__.open", mock.mock_open(read_data='0')), \
+ self.assertRaises(Exception):
+ prepare_env.check_environment()
+
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ def test_check_environment_default(self, mock_logger_info):
+ with mock.patch('functest.ci.prepare_env.os.path.isfile',
+ return_value=True):
+ with mock.patch("__builtin__.open", mock.mock_open(read_data='1')):
+ prepare_env.check_environment()
+ mock_logger_info.assert_any_call("Functest environment"
+ " is installed.")
+
+ @mock.patch('functest.ci.prepare_env.check_environment')
+ @mock.patch('functest.ci.prepare_env.create_flavor')
+ @mock.patch('functest.ci.prepare_env.install_tempest')
+ @mock.patch('functest.ci.prepare_env.install_rally')
+ @mock.patch('functest.ci.prepare_env.verify_deployment')
+ @mock.patch('functest.ci.prepare_env.patch_config_file')
+ @mock.patch('functest.ci.prepare_env.source_rc_file')
+ @mock.patch('functest.ci.prepare_env.create_directories')
+ @mock.patch('functest.ci.prepare_env.check_env_variables')
+ @mock.patch('functest.ci.prepare_env.logger.info')
+ def test_main_start(self, mock_logger_info, mock_env_var,
+ mock_create_dir, mock_source_rc, mock_patch_config,
+ mock_verify_depl, mock_install_rally,
+ mock_install_temp, mock_create_flavor,
+ mock_check_env):
+ with mock.patch("__builtin__.open", mock.mock_open()) as m:
+ args = {'action': 'start'}
+ self.assertEqual(prepare_env.main(**args), 0)
+ mock_logger_info.assert_any_call("######### Preparing Functest "
+ "environment #########\n")
+ self.assertTrue(mock_env_var.called)
+ self.assertTrue(mock_create_dir.called)
+ self.assertTrue(mock_source_rc.called)
+ self.assertTrue(mock_patch_config.called)
+ self.assertTrue(mock_verify_depl.called)
+ self.assertTrue(mock_install_rally.called)
+ self.assertTrue(mock_install_temp.called)
+ self.assertTrue(mock_create_flavor.called)
+ m.assert_called_once_with(CONST.env_active, "w")
+ self.assertTrue(mock_check_env.called)
+
+ @mock.patch('functest.ci.prepare_env.check_environment')
+ def test_main_check(self, mock_check_env):
+ args = {'action': 'check'}
+ self.assertEqual(prepare_env.main(**args), 0)
+ self.assertTrue(mock_check_env.called)
+
+ @mock.patch('functest.ci.prepare_env.logger.error')
+ def test_main_no_arg(self, mock_logger_error):
+ args = {'action': 'not_valid'}
+ self.assertEqual(prepare_env.main(**args), -1)
+ mock_logger_error.assert_called_once_with('Argument not valid.')
+
+
+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 8f2a5d7e4..5961940f1 100644
--- a/functest/tests/unit/odl/test_odl.py
+++ b/functest/tests/unit/odl/test_odl.py
@@ -30,6 +30,7 @@ class ODLTesting(unittest.TestCase):
_keystone_ip = "127.0.0.1"
_neutron_ip = "127.0.0.2"
_sdn_controller_ip = "127.0.0.3"
+ _os_auth_url = "http://{}:5000/v2.0".format(_keystone_ip)
_os_tenantname = "admin"
_os_username = "admin"
_os_password = "admin"
@@ -42,14 +43,15 @@ class ODLTesting(unittest.TestCase):
for var in ("INSTALLER_TYPE", "SDN_CONTROLLER", "SDN_CONTROLLER_IP"):
if var in os.environ:
del os.environ[var]
+ os.environ["OS_AUTH_URL"] = self._os_auth_url
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()
self.defaultargs = {'odlusername': self._odl_username,
'odlpassword': self._odl_password,
- 'keystoneip': self._keystone_ip,
'neutronip': self._keystone_ip,
+ 'osauthurl': self._os_auth_url,
'osusername': self._os_username,
'ostenantname': self._os_tenantname,
'ospassword': self._os_password,
@@ -157,8 +159,8 @@ class ODLTesting(unittest.TestCase):
def _get_main_kwargs(self, key=None):
kwargs = {'odlusername': self._odl_username,
'odlpassword': self._odl_password,
- 'keystoneip': self._keystone_ip,
'neutronip': self._neutron_ip,
+ 'osauthurl': self._os_auth_url,
'osusername': self._os_username,
'ostenantname': self._os_tenantname,
'ospassword': self._os_password,
@@ -178,6 +180,7 @@ class ODLTesting(unittest.TestCase):
if len(args) > 1:
variable = ['KEYSTONE:{}'.format(self._keystone_ip),
'NEUTRON:{}'.format(self._neutron_ip),
+ 'OS_AUTH_URL:"{}"'.format(self._os_auth_url),
'OSUSERNAME:"{}"'.format(self._os_username),
'OSTENANTNAME:"{}"'.format(self._os_tenantname),
'OSPASSWORD:"{}"'.format(self._os_password),
@@ -207,12 +210,12 @@ class ODLTesting(unittest.TestCase):
def test_main_missing_odlpassword(self):
self._test_main_missing_keyword('odlpassword')
- def test_main_missing_keystoneip(self):
- self._test_main_missing_keyword('keystoneip')
-
def test_main_missing_neutronip(self):
self._test_main_missing_keyword('neutronip')
+ def test_main_missing_osauthurl(self):
+ self._test_main_missing_keyword('osauthurl')
+
def test_main_missing_osusername(self):
self._test_main_missing_keyword('osusername')
@@ -347,10 +350,11 @@ class ODLTesting(unittest.TestCase):
self.assertEqual(self.test.run(), status)
self.test.main.assert_called_once_with(
odl.ODLTests.default_suites,
- keystoneip=self._keystone_ip, neutronip=self._neutron_ip,
+ neutronip=self._neutron_ip,
odlip=odlip, odlpassword=self._odl_password,
odlrestconfport=odlrestconfport,
odlusername=self._odl_username, odlwebport=odlwebport,
+ osauthurl=self._os_auth_url,
ospassword=self._os_password, ostenantname=self._os_tenantname,
osusername=self._os_username)
@@ -368,10 +372,11 @@ class ODLTesting(unittest.TestCase):
self.assertEqual(self.test.run(suites=suites), status)
self.test.main.assert_called_once_with(
suites,
- keystoneip=self._keystone_ip, neutronip=self._neutron_ip,
+ neutronip=self._neutron_ip,
odlip=odlip, odlpassword=self._odl_password,
odlrestconfport=odlrestconfport,
odlusername=self._odl_username, odlwebport=odlwebport,
+ osauthurl=self._os_auth_url,
ospassword=self._os_password, ostenantname=self._os_tenantname,
osusername=self._os_username)
@@ -381,6 +386,9 @@ class ODLTesting(unittest.TestCase):
self.assertEqual(self.test.run(),
testcase_base.TestcaseBase.EX_RUN_ERROR)
+ def test_run_missing_os_auth_url(self):
+ self._test_run_missing_env_var("OS_AUTH_URL")
+
def test_run_missing_os_username(self):
self._test_run_missing_env_var("OS_USERNAME")
@@ -507,8 +515,8 @@ class ODLTesting(unittest.TestCase):
def test_argparser_odlpassword(self):
self._test_argparser('odlpassword', 'foo')
- def test_argparser_keystoneip(self):
- self._test_argparser('keystoneip', '127.0.0.4')
+ def test_argparser_osauthurl(self):
+ self._test_argparser('osauthurl', 'http://127.0.0.4:5000/v2')
def test_argparser_neutronip(self):
self._test_argparser('neutronip', '127.0.0.4')
diff --git a/functest/tests/unit/utils/test_openstack_utils.py b/functest/tests/unit/utils/test_openstack_utils.py
index 447271fc6..ef3764cc5 100644
--- a/functest/tests/unit/utils/test_openstack_utils.py
+++ b/functest/tests/unit/utils/test_openstack_utils.py
@@ -104,7 +104,6 @@ class OSUtilsTesting(unittest.TestCase):
'servers.create.return_value': self.instance,
'flavors.list.return_value': [self.flavor],
'flavors.find.return_value': self.flavor,
- 'flavors.list.return_value': [self.flavor],
'servers.add_floating_ip.return_value': mock.Mock(),
'servers.force_delete.return_value': mock.Mock(),
'aggregates.list.return_value': [self.aggregate],
@@ -162,6 +161,15 @@ class OSUtilsTesting(unittest.TestCase):
}
self.cinder_client.configure_mock(**attrs)
+ self.resource = mock.Mock()
+ attrs = {'id': 'resource_test_id',
+ 'name': 'resource_test_name'
+ }
+
+ self.heat_client = mock.Mock()
+ attrs = {'resources.get.return_value': self.resource}
+ self.heat_client.configure_mock(**attrs)
+
mock_obj = mock.Mock()
attrs = {'id': 'tenant_id',
'name': 'test_tenant'}
@@ -543,6 +551,36 @@ class OSUtilsTesting(unittest.TestCase):
mock_glan_client.assert_called_once_with('3',
session=mock_session_obj)
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value=None)
+ def test_get_heat_client_version_missing_env(self, mock_os_getenv):
+ self.assertEqual(openstack_utils.get_heat_client_version(),
+ openstack_utils.DEFAULT_HEAT_API_VERSION)
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ @mock.patch('functest.utils.openstack_utils.os.getenv', return_value='1')
+ def test_get_heat_client_version_default(self, mock_os_getenv,
+ mock_logger_info):
+ self.assertEqual(openstack_utils.get_heat_client_version(), '1')
+ mock_logger_info.assert_called_once_with(
+ "OS_ORCHESTRATION_API_VERSION is set in env as '%s'", '1')
+
+ def test_get_heat_client(self):
+ mock_heat_obj = mock.Mock()
+ mock_session_obj = mock.Mock()
+ with mock.patch('functest.utils.openstack_utils'
+ '.get_heat_client_version', return_value='1'), \
+ mock.patch('functest.utils.openstack_utils'
+ '.heatclient.Client',
+ return_value=mock_heat_obj) \
+ as mock_heat_client, \
+ mock.patch('functest.utils.openstack_utils.get_session',
+ return_value=mock_session_obj):
+ self.assertEqual(openstack_utils.get_heat_client(),
+ mock_heat_obj)
+ mock_heat_client.assert_called_once_with('1',
+ session=mock_session_obj)
+
def test_get_instances_default(self):
self.assertEqual(openstack_utils.get_instances(self.nova_client),
[self.instance])
@@ -1700,6 +1738,24 @@ class OSUtilsTesting(unittest.TestCase):
'user_id'))
self.assertTrue(mock_logger_error.called)
+ def test_get_resource_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=True):
+ self.assertEqual(openstack_utils.
+ get_resource(self.heat_client,
+ 'stack_id',
+ 'resource'),
+ self.resource)
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_resource_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_resource(Exception,
+ 'stack_id',
+ 'resource'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
if __name__ == "__main__":
unittest.main(verbosity=2)
diff --git a/functest/utils/functest_constants.py b/functest/utils/functest_constants.py
deleted file mode 100644
index 0a9a03b18..000000000
--- a/functest/utils/functest_constants.py
+++ /dev/null
@@ -1,218 +0,0 @@
-#!/usr/bin/env python
-#
-# yaohelan@huawei.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 os
-
-import functest.utils.functest_logger as ft_logger
-import functest.utils.functest_utils as ft_utils
-
-logger = ft_logger.Logger("functest_constants").getLogger()
-
-
-""" global variables """
-INSTALLERS = ['fuel', 'compass', 'apex', 'joid']
-CI_INSTALLER_TYPE = os.getenv('INSTALLER_TYPE')
-CI_INSTALLER_IP = os.getenv('INSTALLER_IP')
-CI_SCENARIO = os.getenv('DEPLOY_SCENARIO')
-CI_NODE = os.getenv('NODE_NAME')
-CI_BUILD_TAG = os.getenv('BUILD_TAG')
-CI_DEBUG = os.getenv('CI_DEBUG')
-CI_LOOP = os.getenv('CI_LOOP')
-OS_AUTH_URL = os.getenv('OS_AUTH_URL')
-OS_USERNAME = os.getenv('OS_USERNAME')
-OS_TENANT_NAME = os.getenv('OS_TENANT_NAME')
-OS_PASSWORD = os.getenv('OS_PASSWORD')
-OS_ENDPOINT_TYPE = os.getenv('OS_ENDPOINT_TYPE')
-OS_REGION_NAME = os.getenv('OS_REGION_NAME')
-OS_CACERT = os.getenv('OS_CACERT')
-FUEL_ENV = os.getenv('FUEL_ENV')
-SDN_CONTROLLER_IP = os.getenv('SDN_CONTROLLER_IP')
-SDN_CONTROLLER = os.getenv('SDN_CONTROLLER')
-
-if CI_BUILD_TAG is not None:
- IS_CI_RUN = True
-else:
- IS_CI_RUN = False
-
-CONFIG_FUNCTEST_YAML = os.getenv("CONFIG_FUNCTEST_YAML")
-
-
-def get_value(functest_config_key, env_variable):
- try:
- constant = ft_utils.get_functest_config(functest_config_key)
- # logger.debug("%s is defined in config_functest.yaml as [%s]"
- # % (env_variable, constant))
- return constant
- except ValueError:
- logger.warning("%s is not defined in config_functest.yaml"
- % functest_config_key)
- constant = os.getenv(env_variable)
- if constant is None:
- raise ValueError("%s is neither defined in config_functest.yaml"
- " nor environment variable" % env_variable)
- else:
- logger.debug("%s is defined as environment variable as [%s]"
- % (env_variable, constant))
- return constant
-
-
-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.dir.repo_functest',
- 'FUNCTEST_REPO_DIR')
-FUNCTEST_TEST_DIR = get_value('general.dir.functest_test',
- 'FUNCTEST_TEST_DIR')
-FUNCTEST_CONF_DIR = get_value('general.dir.functest_conf',
- 'FUNCTEST_CONF_DIR')
-FUNCTEST_DATA_DIR = get_value('general.dir.functest_data',
- 'FUNCTEST_DATA_DIR')
-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.dir.repo_tempest',
- 'TEMPEST_REPO_DIR')
-
-ENV_FILE = os.path.join(FUNCTEST_CONF_DIR, "env_active")
-
-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.dir.repo_domino',
- 'DOMINO_REPO_DIR')
-SDNVPN_REPO_DIR = get_value('general.dir.repo_sdnvpn',
- 'SDNVPN_REPO_DIR')
-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.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.dir.rally',
- 'RALLY_RELATIVE_PATH')
-RALLY_PRIVATE_NET_NAME = get_value('rally.network_name',
- 'RALLY_PRIVATE_NET_NAME')
-RALLY_PRIVATE_SUBNET_NAME = get_value('rally.subnet_name',
- 'RALLY_PRIVATE_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.dir.rally_inst',
- 'RALLY_INSTALLATION_DIR')
-GLANCE_IMAGE_NAME = get_value('general.openstack.image_name',
- 'GLANCE_IMAGE_NAME')
-GLANCE_IMAGE_FILENAME = get_value('general.openstack.image_file_name',
- 'GLANCE_IMAGE_FILENAME')
-GLANCE_IMAGE_FORMAT = get_value('general.openstack.image_disk_format',
- 'GLANCE_IMAGE_FORMAT')
-FLAVOR_NAME = get_value('general.openstack.flavor_name',
- 'FLAVOR_NAME')
-FLAVOR_RAM = get_value('general.openstack.flavor_ram',
- 'FLAVOR_RAM')
-FLAVOR_DISK = get_value('general.openstack.flavor_disk',
- 'FLAVOR_DISK')
-FLAVOR_VCPUS = get_value('general.openstack.flavor_vcpus',
- 'FLAVOR_VCPUS')
-TEMPEST_PRIVATE_NET_NAME = get_value('tempest.private_net_name',
- 'TEMPEST_PRIVATE_NET_NAME')
-TEMPEST_PRIVATE_SUBNET_NAME = get_value('tempest.private_subnet_name',
- 'TEMPEST_PRIVATE_SUBNET_NAME')
-TEMPEST_PRIVATE_SUBNET_CIDR = get_value('tempest.private_subnet_cidr',
- 'TEMPEST_PRIVATE_SUBNET_CIDR')
-TEMPEST_ROUTER_NAME = get_value('tempest.router_name',
- 'TEMPEST_ROUTER_NAME')
-TEMPEST_TENANT_NAME = get_value('tempest.identity.tenant_name',
- 'TEMPEST_TENANT_NAME')
-TEMPEST_TENANT_DESCRIPTION = get_value('tempest.identity.tenant_description',
- 'TEMPEST_TENANT_DESCRIPTION')
-TEMPEST_USER_NAME = get_value('tempest.identity.user_name',
- 'TEMPEST_USER_NAME')
-TEMPEST_USER_PASSWORD = get_value('tempest.identity.user_password',
- 'TEMPEST_USER_PASSWORD')
-TEMPEST_SSH_TIMEOUT = get_value('tempest.validation.ssh_timeout',
- 'TEMPEST_SSH_TIMEOUT')
-TEMPEST_OPERATOR_ROLE = get_value('tempest.object_storage.operator_role',
- 'TEMPEST_OPERATOR_ROLE')
-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.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.private_net_name',
- 'VPING_PRIVATE_NET_NAME')
-VPING_PRIVATE_SUBNET_NAME = get_value('vping.private_subnet_name',
- 'VPING_PRIVATE_SUBNET_NAME')
-VPING_PRIVATE_SUBNET_CIDR = get_value('vping.private_subnet_cidr',
- 'VPING_PRIVATE_SUBNET_CIDR')
-VPING_ROUTER_NAME = get_value('vping.router_name',
- 'VPING_ROUTER_NAME')
-VPING_SECGROUP_NAME = get_value('vping.sg_name',
- 'VPING_SECGROUP_NAME')
-VPING_SECGROUP_DESCR = get_value('vping.sg_desc',
- 'VPING_SECGROUP_DESCR')
-ONOSBENCH_USERNAME = get_value('ONOS.general.onosbench_username',
- 'ONOSBENCH_USERNAME')
-ONOSBENCH_PASSWORD = get_value('ONOS.general.onosbench_password',
- 'ONOSBENCH_PASSWORD')
-ONOSCLI_USERNAME = get_value('ONOS.general.onoscli_username',
- 'ONOSCLI_USERNAME')
-ONOSCLI_PASSWORD = get_value('ONOS.general.onoscli_password',
- 'ONOSCLI_PASSWORD')
-ONOS_RUNTIMEOUT = get_value('ONOS.general.runtimeout',
- 'ONOS_RUNTIMEOUT')
-ONOS_OCT = get_value('ONOS.environment.OCT', 'ONOS_OCT')
-ONOS_OC1 = get_value('ONOS.environment.OC1', 'ONOS_OC1')
-ONOS_OC2 = get_value('ONOS.environment.OC2', 'ONOS_OC2')
-ONOS_OC3 = get_value('ONOS.environment.OC3', 'ONOS_OC3')
-ONOS_OCN = get_value('ONOS.environment.OCN', 'ONOS_OCN')
-ONOS_OCN2 = get_value('ONOS.environment.OCN2', 'ONOS_OCN2')
-ONOS_INSTALLER_MASTER = get_value('ONOS.environment.installer_master',
- 'ONOS_INSTALLER_MASTER')
-ONOS_INSTALLER_MASTER_USERNAME = get_value(
- 'ONOS.environment.installer_master_username',
- 'ONOS_INSTALLER_MASTER_USERNAME')
-ONOS_INSTALLER_MASTER_PASSWORD = get_value(
- 'ONOS.environment.installer_master_password',
- 'ONOS_INSTALLER_MASTER_PASSWORD')
-EXAMPLE_INSTANCE_NAME = get_value('example.vm_name',
- 'EXAMPLE_INSTANCE_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.private_net_name',
- 'EXAMPLE_PRIVATE_NET_NAME')
-EXAMPLE_PRIVATE_SUBNET_NAME = get_value(
- 'example.private_subnet_name',
- 'EXAMPLE_PRIVATE_SUBNET_NAME')
-EXAMPLE_PRIVATE_SUBNET_CIDR = get_value(
- 'example.private_subnet_cidr',
- 'EXAMPLE_PRIVATE_SUBNET_CIDR')
-EXAMPLE_ROUTER_NAME = get_value('example.router_name',
- 'EXAMPLE_ROUTER_NAME')
-EXAMPLE_SECGROUP_NAME = get_value('example.sg_name',
- 'EXAMPLE_SECGROUP_NAME')
-EXAMPLE_SECGROUP_DESCR = get_value('example.sg_desc',
- 'EXAMPLE_SECGROUP_DESCR')
-PARSER_REPO_DIR = get_value('general.dir.repo_parser',
- 'PARSER_REPO_DIR')
diff --git a/functest/utils/openstack_utils.py b/functest/utils/openstack_utils.py
index 3093cb558..e33af63b4 100755
--- a/functest/utils/openstack_utils.py
+++ b/functest/utils/openstack_utils.py
@@ -18,6 +18,7 @@ from keystoneauth1 import loading
from keystoneauth1 import session
from cinderclient import client as cinderclient
from glanceclient import client as glanceclient
+from heatclient import client as heatclient
from novaclient import client as novaclient
from keystoneclient import client as keystoneclient
from neutronclient.neutron import client as neutronclient
@@ -28,6 +29,7 @@ import functest.utils.functest_utils as ft_utils
logger = ft_logger.Logger("openstack_utils").getLogger()
DEFAULT_API_VERSION = '2'
+DEFAULT_HEAT_API_VERSION = '1'
# *********************************************
@@ -241,6 +243,20 @@ def get_glance_client(other_creds={}):
return glanceclient.Client(get_glance_client_version(), session=sess)
+def get_heat_client_version():
+ api_version = os.getenv('OS_ORCHESTRATION_API_VERSION')
+ if api_version is not None:
+ logger.info("OS_ORCHESTRATION_API_VERSION is set in env as '%s'",
+ api_version)
+ return api_version
+ return DEFAULT_HEAT_API_VERSION
+
+
+def get_heat_client(other_creds={}):
+ sess = get_session(other_creds)
+ return heatclient.Client(get_heat_client_version(), session=sess)
+
+
# *********************************************
# NOVA
# *********************************************
@@ -985,36 +1001,43 @@ def create_security_group(neutron_client, sg_name, sg_description):
def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
port_range_min=None, port_range_max=None):
- if port_range_min is None and port_range_max is None:
- json_body = {'security_group_rule': {'direction': direction,
- 'security_group_id': sg_id,
- 'protocol': protocol}}
- elif port_range_min is not None and port_range_max is not None:
- json_body = {'security_group_rule': {'direction': direction,
- 'security_group_id': sg_id,
- 'port_range_min': port_range_min,
- 'port_range_max': port_range_max,
- 'protocol': protocol}}
+ # We create a security group in 2 steps
+ # 1 - we check the format and set the json body accordingly
+ # 2 - we call neturon client to create the security group
+
+ # Format check
+ json_body = {'security_group_rule': {'direction': direction,
+ 'security_group_id': sg_id,
+ 'protocol': protocol}}
+ # parameters may be
+ # - both None => we do nothing
+ # - both Not None => we add them to the json description
+ # but one cannot be None is the other is not None
+ if (port_range_min is not None and port_range_max is not None):
+ # add port_range in json description
+ json_body['security_group_rule']['port_range_min'] = port_range_min
+ json_body['security_group_rule']['port_range_max'] = port_range_max
+ logger.debug("Security_group format set (port range included)")
else:
- logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
- "'%s', '%s', '%s', '%s')]:" % (neutron_client,
- sg_id, direction,
- port_range_min,
- port_range_max,
- protocol),
- " Invalid values for port_range_min, port_range_max")
- return False
+ # either both port range are set to None => do nothing
+ # or one is set but not the other => log it and return False
+ if port_range_min is None and port_range_max is None:
+ logger.debug("Security_group format set (no port range mentioned)")
+ else:
+ logger.error("Bad security group format."
+ "One of the port range is not properly set:"
+ "range min: {},"
+ "range max: {}".format(port_range_min,
+ port_range_max))
+ return False
+
+ # Create security group using neutron client
try:
neutron_client.create_security_group_rule(json_body)
return True
- except Exception, e:
- logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
- "'%s', '%s', '%s', '%s')]: %s" % (neutron_client,
- sg_id,
- direction,
- port_range_min,
- port_range_max,
- protocol, e))
+ except:
+ logger.exception("Impossible to create_security_group_rule,"
+ "security group rule probably already exists")
return False
@@ -1383,3 +1406,15 @@ def delete_user(keystone_client, user_id):
logger.error("Error [delete_user(keystone_client, '%s')]: %s"
% (user_id, e))
return False
+
+
+# *********************************************
+# HEAT
+# *********************************************
+def get_resource(heat_client, stack_id, resource):
+ try:
+ resources = heat_client.resources.get(stack_id, resource)
+ return resources
+ except Exception, e:
+ logger.error("Error [get_resource]: %s" % e)
+ return None
diff --git a/requirements.txt b/requirements.txt
index 68b889b35..ee629eab8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,6 +9,7 @@ pyyaml==3.10
gitpython==1.0.1
python-openstackclient==2.3.0
python-ceilometerclient==2.6.2
+python-heatclient==1.7.0
python-keystoneclient==3.5.0
python-neutronclient==6.0.0
python-novaclient==6.0.0
diff --git a/run_unit_tests.sh b/run_unit_tests.sh
index 7cad227e0..32076dabe 100755
--- a/run_unit_tests.sh
+++ b/run_unit_tests.sh
@@ -25,11 +25,10 @@ pip install -r $WORKSPACE/test-requirements.txt
pip install $WORKSPACE
#install releng
-cd $WORKSPACE/../
-git clone https://gerrit.opnfv.org/gerrit/releng
-pip install releng/modules/
-rm -fr releng
-cd $WORKSPACE
+rm -rf releng-unittests
+git clone --depth 1 https://gerrit.opnfv.org/gerrit/releng releng-unittests
+pip install releng-unittests/modules/
+rm -fr releng-unittests
export CONFIG_FUNCTEST_YAML=$(pwd)/functest/ci/config_functest.yaml
# unit tests
@@ -39,6 +38,7 @@ nosetests --with-xunit \
--with-coverage \
--cover-erase \
--cover-tests \
+ --cover-package=functest.ci \
--cover-package=functest.cli \
--cover-package=functest.core.testcase_base \
--cover-package=functest.opnfv_tests.sdn.odl.odl \
diff --git a/test-requirements.txt b/test-requirements.txt
index 16466b8a3..471e9c30a 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -14,6 +14,7 @@ mock==1.3.0
nose==1.3.7
python-ceilometerclient==2.6.2
python-congressclient==1.5.0
+python-heatclient==1.7.0
python-keystoneclient==3.5.0
python-neutronclient==6.0.0
python-openstackclient==2.3.0