aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)0
-rw-r--r--docs/testing/developer/devguide/index.rst (renamed from docs/devguide/index.rst)26
-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)0
-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
-rwxr-xr-xfunctest/ci/config_functest.yaml12
-rwxr-xr-xfunctest/ci/config_patch.yaml6
-rwxr-xr-xfunctest/ci/exec_test.sh6
-rwxr-xr-xfunctest/ci/prepare_env.py58
-rwxr-xr-xfunctest/ci/testcases.yaml27
-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/tempest/custom_tests/blacklist.txt19
-rw-r--r--functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt4
-rw-r--r--functest/opnfv_tests/openstack/tempest/tempest.py6
-rw-r--r--functest/opnfv_tests/sdn/onos/__init__.py0
-rw-r--r--functest/opnfv_tests/sdn/onos/onos.py225
-rwxr-xr-xfunctest/opnfv_tests/sdn/onos/teston/onos.py261
-rw-r--r--functest/tests/unit/utils/test_openstack_utils.py58
-rwxr-xr-x[-rw-r--r--]functest/utils/config.py20
-rw-r--r--functest/utils/functest_constants.py9
-rwxr-xr-xfunctest/utils/openstack_utils.py87
-rw-r--r--requirements.txt1
-rw-r--r--test-requirements.txt1
34 files changed, 486 insertions, 426 deletions
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..6c6d18109 100644
--- a/docs/release-notes/index.rst
+++ b/docs/release/release-notes/index.rst
diff --git a/docs/devguide/index.rst b/docs/testing/developer/devguide/index.rst
index eee013678..11ca241b2 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:
@@ -260,9 +260,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 +500,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 +627,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..08e089c2b 100644
--- a/docs/configguide/configguide.rst
+++ b/docs/testing/user/configguide/configguide.rst
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_functest.yaml b/functest/ci/config_functest.yaml
index 489c395ff..402e29999 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
@@ -43,8 +43,8 @@ general:
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 +67,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
index aa0cfaf7e..6f776101d 100755
--- a/functest/ci/exec_test.sh
+++ b/functest/ci/exec_test.sh
@@ -94,12 +94,6 @@ function run_test(){
--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
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/testcases.yaml b/functest/ci/testcases.yaml
index f8bbe9b74..722e8796d 100755
--- a/functest/ci/testcases.yaml
+++ b/functest/ci/testcases.yaml
@@ -78,7 +78,7 @@ tiers:
over a private network.
dependencies:
installer: ''
- scenario: '^((?!bgpvpn|odl_l3).)*$'
+ scenario: '^((?!odl_l3).)*$'
run:
module: 'functest.opnfv_tests.openstack.vping.vping_ssh'
class: 'VPingSSH'
@@ -125,7 +125,7 @@ tiers:
Rally suite in smoke mode.
dependencies:
installer: ''
- scenario: '^((?!bgpvpn).)*$'
+ scenario: ''
run:
module: 'functest.opnfv_tests.openstack.rally.rally'
class: 'RallySanity'
@@ -184,7 +184,9 @@ tiers:
dependencies:
installer: ''
scenario: 'onos'
-
+ run:
+ module: 'functest.opnfv_tests.sdn.onos.onos'
+ class: 'Onos'
-
name: snaps_smoke
@@ -319,6 +321,9 @@ tiers:
dependencies:
installer: ''
scenario: 'onos-sfc'
+ run:
+ module: 'functest.opnfv_tests.sdn.onos.onos'
+ class: 'OnosSfc'
-
name: parser
criteria: 'ret == 0'
@@ -423,6 +428,22 @@ tiers:
run:
module: 'functest.opnfv_tests.openstack.tempest.tempest'
class: 'TempestDefcore'
+ -
+ name: tempest_custom
+ criteria: 'success_rate == 100%'
+ blocking: false
+ description: >-
+ The test case allows running a customized list of tempest
+ test cases defined in a file under
+ <dir_functest_repo>/functest/opnfv_tests/openstack/
+ /tempest/custom_tests/test_list.txt
+ The file is empty and can be customized with the desired tests.
+ dependencies:
+ installer: 'unknown'
+ scenario: 'unknown'
+ run:
+ module: 'functest.opnfv_tests.openstack.tempest.tempest'
+ class: 'TempestCustom'
# -
# name: rally_full
# criteria: 'success_rate >= 90%'
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/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/custom_tests/test_list.txt b/functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt
new file mode 100644
index 000000000..ac4e37289
--- /dev/null
+++ b/functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt
@@ -0,0 +1,4 @@
+# This is an empty file to be filled up with the desired tempest test cases
+# Examples:
+#tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops
+#tempest.scenario.test_network_basic_ops.TestNetworkBasicOps.test_network_basic_ops \ No newline at end of file
diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py
index 37b5c0ee7..4c96500db 100644
--- a/functest/opnfv_tests/openstack/tempest/tempest.py
+++ b/functest/opnfv_tests/openstack/tempest/tempest.py
@@ -324,11 +324,11 @@ class TempestMultisite(TempestCommon):
class TempestCustom(TempestCommon):
- def __init__(self, mode, option):
+ def __init__(self):
TempestCommon.__init__(self)
self.case_name = "tempest_custom"
- self.MODE = mode
- self.OPTION = option
+ self.MODE = "custom"
+ self.OPTION = "--concurrency 1"
class TempestDefcore(TempestCommon):
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/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/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/config.py b/functest/utils/config.py
index 84166c1d3..b5b845010 100644..100755
--- a/functest/utils/config.py
+++ b/functest/utils/config.py
@@ -2,26 +2,25 @@ import os
import yaml
+import env
+
class Config(object):
def __init__(self):
- if 'CONFIG_FUNCTEST_YAML' not in os.environ:
- raise Exception('CONFIG_FUNCTEST_YAML not configed')
- self.config_functest = os.environ['CONFIG_FUNCTEST_YAML']
try:
- with open(self.config_functest) as f:
+ with open(env.ENV.CONFIG_FUNCTEST_YAML) as f:
self.functest_yaml = yaml.safe_load(f)
self._parse(None, self.functest_yaml)
- except:
- raise Exception('Parse {} failed'.format(self.config_functest))
+ except Exception as error:
+ raise Exception('Parse config failed: {}'.format(str(error)))
self._set_others()
def _parse(self, attr_now, left_parametes):
for param_n, param_v in left_parametes.iteritems():
attr_further = self._get_attr_further(attr_now, param_n)
- if not isinstance(param_v, dict):
+ if attr_further:
self.__setattr__(attr_further, param_v)
- else:
+ if isinstance(param_v, dict):
self._parse(attr_further, param_v)
def _get_attr_further(self, attr_now, next):
@@ -33,3 +32,8 @@ class Config(object):
CONF = Config()
+
+if __name__ == "__main__":
+ print CONF.vnf_cloudify_ims
+ print CONF.vnf_cloudify_ims_tenant_images
+ print CONF.vnf_cloudify_ims_tenant_images_centos_7
diff --git a/functest/utils/functest_constants.py b/functest/utils/functest_constants.py
index 0a9a03b18..9fae9a9c0 100644
--- a/functest/utils/functest_constants.py
+++ b/functest/utils/functest_constants.py
@@ -94,15 +94,6 @@ 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',
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/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