aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build.sh3
-rw-r--r--docker/Dockerfile6
-rw-r--r--docker/features/testcases.yaml2
-rw-r--r--docker/vnf/testcases.yaml16
-rw-r--r--docs/testing/developer/devguide/index.rst3
-rw-r--r--docs/testing/user/configguide/configguide.rst6
-rw-r--r--docs/testing/user/userguide/runfunctest.rst2
-rw-r--r--docs/testing/user/userguide/test_details.rst45
-rw-r--r--docs/testing/user/userguide/test_overview.rst6
-rw-r--r--functest/api/base.py5
-rw-r--r--functest/api/resources/v1/envs.py41
-rw-r--r--functest/api/resources/v1/tasks.py43
-rw-r--r--functest/api/resources/v1/testcases.py19
-rw-r--r--functest/api/urls.py11
-rw-r--r--functest/ci/config_functest.yaml29
-rw-r--r--functest/ci/download_images.sh5
-rw-r--r--functest/ci/testcases.yaml44
-rw-r--r--functest/opnfv_tests/mano/orchestra.py27
-rw-r--r--functest/opnfv_tests/openstack/rally/blacklist.txt10
-rw-r--r--functest/opnfv_tests/openstack/refstack_client/refstack_client.py21
-rw-r--r--functest/opnfv_tests/openstack/snaps/snaps_test_runner.py3
-rw-r--r--functest/opnfv_tests/openstack/tempest/tempest.py17
-rw-r--r--functest/opnfv_tests/openstack/vping/vping_base.py3
-rw-r--r--functest/opnfv_tests/sdn/onos/onos.py232
-rw-r--r--functest/opnfv_tests/sdn/onos/sfc/README.md21
-rw-r--r--functest/opnfv_tests/sdn/onos/sfc/sfc.py174
-rw-r--r--functest/opnfv_tests/sdn/onos/sfc/sfc_onos.py887
-rw-r--r--functest/opnfv_tests/sdn/onos/teston/Readme.txt5
-rw-r--r--functest/opnfv_tests/sdn/onos/teston/adapters/client.py92
-rw-r--r--functest/opnfv_tests/sdn/onos/teston/adapters/connection.py200
-rw-r--r--functest/opnfv_tests/sdn/onos/teston/adapters/environment.py286
-rw-r--r--functest/opnfv_tests/sdn/onos/teston/adapters/foundation.py95
-rw-r--r--functest/opnfv_tests/sdn/onos/teston/dependencies/onos29
-rw-r--r--functest/opnfv_tests/sdn/onos/teston/log/gitignore0
-rw-r--r--functest/opnfv_tests/vnf/ims/cloudify_ims.py27
-rw-r--r--functest/opnfv_tests/vnf/ims/orchestra_clearwaterims.py3
-rw-r--r--functest/opnfv_tests/vnf/ims/orchestra_openims.py3
-rw-r--r--functest/opnfv_tests/vnf/router/cloudify_vrouter.py542
-rw-r--r--functest/opnfv_tests/vnf/router/cloudify_vrouter.yaml31
-rw-r--r--functest/opnfv_tests/vnf/router/test_controller/__init__.py (renamed from functest/opnfv_tests/sdn/onos/__init__.py)0
-rw-r--r--functest/opnfv_tests/vnf/router/test_controller/function_test_exec.py137
-rw-r--r--functest/opnfv_tests/vnf/router/test_scenario.yaml27
-rw-r--r--functest/opnfv_tests/vnf/router/utilvnf.py345
-rw-r--r--functest/opnfv_tests/vnf/router/vnf_controller/__init__.py (renamed from functest/opnfv_tests/sdn/onos/teston/__init__.py)0
-rw-r--r--functest/opnfv_tests/vnf/router/vnf_controller/checker.py59
-rw-r--r--functest/opnfv_tests/vnf/router/vnf_controller/command_generator.py32
-rw-r--r--functest/opnfv_tests/vnf/router/vnf_controller/ssh_client.py131
-rw-r--r--functest/opnfv_tests/vnf/router/vnf_controller/vm_controller.py148
-rw-r--r--functest/opnfv_tests/vnf/router/vnf_controller/vnf_controller.py136
-rw-r--r--functest/opnfv_tests/vnf/router/vrouter_base.py119
-rw-r--r--functest/opnfv_tests/vnf/router/vyos_vrouter.py34
-rw-r--r--functest/tests/unit/utils/test_functest_utils.py43
-rw-r--r--functest/tests/unit/vnf/router/__init__.py (renamed from functest/opnfv_tests/sdn/onos/teston/adapters/__init__.py)0
-rw-r--r--functest/tests/unit/vnf/router/test_cloudify_vrouter.py140
-rw-r--r--functest/tests/unit/vnf/router/test_vrouter_base.py28
-rw-r--r--functest/utils/functest_utils.py29
-rw-r--r--requirements.txt1
-rw-r--r--setup.cfg1
-rw-r--r--upper-constraints.txt1
59 files changed, 2088 insertions, 2317 deletions
diff --git a/build.sh b/build.sh
index 77ea98be..95bea6f3 100644
--- a/build.sh
+++ b/build.sh
@@ -8,7 +8,8 @@ docker/core \
docker/healthcheck \
docker/smoke \
docker/features \
-docker/components"
+docker/components \
+docker/vnf"
(cd docker && docker build -t "${repo}/functest" .)
docker push "${repo}/functest"
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 0e896d6d..d60ce53b 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -17,7 +17,6 @@ ARG RALLY_TAG=0.8.1
ARG ODL_TAG=release/carbon
ARG OPENSTACK_TAG=stable/ocata
ARG VIMS_TAG=stable
-ARG VROUTER_TAG=stable
ARG REPOS_DIR=/home/opnfv/repos
ARG FUNCTEST_BASE_DIR=/home/opnfv/functest
ARG FUNCTEST_CONF_DIR=${FUNCTEST_BASE_DIR}/conf
@@ -93,11 +92,6 @@ RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/fds /src/fds
# other repositories
RUN git clone --depth 1 -b $ODL_TAG https://git.opendaylight.org/gerrit/p/integration/test.git /src/odl_test
RUN git clone --depth 1 -b $VIMS_TAG https://github.com/boucherv-orange/clearwater-live-test /src/vims-test
-RUN git clone --depth 1 -b $VROUTER_TAG https://github.com/oolorg/opnfv-functest-vrouter.git ${REPOS_VNFS_DIR}/vrouter
-RUN git clone --depth 1 https://github.com/wuwenbin2/OnosSystemTest.git ${REPOS_DIR}/onos
-
-# SFC integration
-RUN /bin/bash -c ". /usr/local/lib/python2.7/dist-packages/sfc/tests/functest/setup_scripts/tacker_client_install.sh"
# Install tempest venv and create symlink for running refstack-client
RUN ln -s /src/tempest /src/refstack-client/.tempest \
diff --git a/docker/features/testcases.yaml b/docker/features/testcases.yaml
index 69da9350..da83232b 100644
--- a/docker/features/testcases.yaml
+++ b/docker/features/testcases.yaml
@@ -54,7 +54,7 @@ tiers:
module: 'functest.core.feature'
class: 'BashFeature'
args:
- cmd: '. /home/opnfv/functest/conf/stackrc && security_scan --config /usr/local/etc/securityscanning/config.ini'
+ cmd: '. /home/opnfv/functest/conf/stackrc && security_scan --config /usr/etc/securityscanning/config.ini'
-
case_name: functest-odl-sfc
diff --git a/docker/vnf/testcases.yaml b/docker/vnf/testcases.yaml
index 9f653393..c0eba822 100644
--- a/docker/vnf/testcases.yaml
+++ b/docker/vnf/testcases.yaml
@@ -9,7 +9,7 @@ tiers:
-
case_name: cloudify_ims
project_name: functest
- criteria: 100
+ criteria: 80
blocking: false
description: >-
This test case deploys an OpenSource vIMS solution from Clearwater
@@ -47,3 +47,17 @@ tiers:
run:
module: 'functest.opnfv_tests.vnf.ims.orchestra_clearwaterims'
class: 'ClearwaterImsVnf'
+
+ -
+ case_name: vyos_vrouter
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case is vRouter testing.
+ dependencies:
+ installer: 'fuel'
+ scenario: 'nosdn-nofeature'
+ run:
+ module: 'functest.opnfv_tests.vnf.router.cloudify_vrouter'
+ class: 'CloudifyVrouter'
diff --git a/docs/testing/developer/devguide/index.rst b/docs/testing/developer/devguide/index.rst
index 6bc46081..8a8b09cb 100644
--- a/docs/testing/developer/devguide/index.rst
+++ b/docs/testing/developer/devguide/index.rst
@@ -126,7 +126,7 @@ The structure of this repository is detailed in `[1]`_.
The main internal test cases are in the opnfv_tests subfolder of the
repository, the internal test cases are:
- * sdn: odl, odl_netvirt, odl_fds, onos
+ * sdn: odl, odl_netvirt, odl_fds
* openstack: api_check, connection_check, snaps_health_check, vping_ssh, vping_userdata, tempest_*, rally_*
* vnf: cloudify_ims
@@ -144,7 +144,6 @@ The external test cases are:
* bgpvpn
* doctor
* domino
- * onos
* fds
* orchestra_ims
* parser
diff --git a/docs/testing/user/configguide/configguide.rst b/docs/testing/user/configguide/configguide.rst
index 716c8a13..d19939af 100644
--- a/docs/testing/user/configguide/configguide.rst
+++ b/docs/testing/user/configguide/configguide.rst
@@ -120,7 +120,7 @@ recommended parameters for invoking docker container
-e "DEPLOY_SCENARIO=os-<controller>-<nfv_feature>-<ha_mode>"
where:
os = OpenStack (No other VIM choices currently available)
- controller is one of ( nosdn | odl_l2 | odl_l3 | onos | ocl)
+ controller is one of ( nosdn | odl_l2 | odl_l3 )
nfv_feature is one or more of ( ovs | kvm | sfc | bgpvpn | nofeature )
If several features are pertinent then use the underscore
character '_' to separate each feature (e.g. ovs_kvm)
@@ -319,7 +319,6 @@ should now be in place::
| | |-- images
| | `-- results
| `-- repos
- | |-- onos
| |-- doctor
| `-- vnfs
-- src
@@ -426,8 +425,7 @@ follows::
│   │   |-- tempest
│   │   `-- vping
│   |-- sdn
- │   │   |-- odl
- │   │   `-- onos
+ │   │   `-- odl
│   `-- vnf
│   |-- aaa
│   |-- ims
diff --git a/docs/testing/user/userguide/runfunctest.rst b/docs/testing/user/userguide/runfunctest.rst
index c8db6ff1..83e603b3 100644
--- a/docs/testing/user/userguide/runfunctest.rst
+++ b/docs/testing/user/userguide/runfunctest.rst
@@ -256,7 +256,7 @@ variables:
* Installer IP of the engine or VM running the actual deployment, stored in INSTALLER_IP
* The scenario [controller]-[feature]-[mode], stored in DEPLOY_SCENARIO with
- * controller = (odl|ocl|nosdn|onos)
+ * controller = (odl|ocl|nosdn)
* feature = (ovs(dpdk)|kvm|sfc|bgpvpn|ovs_dpdk_bar)
* mode = (ha|noha)
diff --git a/docs/testing/user/userguide/test_details.rst b/docs/testing/user/userguide/test_details.rst
index 5f5be417..f23abc50 100644
--- a/docs/testing/user/userguide/test_details.rst
+++ b/docs/testing/user/userguide/test_details.rst
@@ -376,51 +376,6 @@ Note: the checks in OpenDaylight are based on the returned HTTP status
code returned by OpenDaylight.
-ONOS
-^^^^
-
-TestON Framework is used to test the ONOS SDN controller functions.
-The test cases deal with L2 and L3 functions.
-The ONOS test suite can be run on any ONOS compliant scenario.
-
-The test cases are described as follows:
-
- * onosfunctest: The main executable file contains the initialization of
- the docker environment and functions called by FUNCvirNetNB and
- FUNCvirNetNBL3
-
- * FUNCvirNetNB
-
- * Create Network: Post Network data and check it in ONOS
- * Update Network: Update the Network and compare it in ONOS
- * Delete Network: Delete the Network and check if it's NULL in ONOS or
- not
- * Create Subnet: Post Subnet data and check it in ONOS
- * Update Subnet: Update the Subnet and compare it in ONOS
- * Delete Subnet: Delete the Subnet and check if it's NULL in ONOS or not
- * Create Port: Post Port data and check it in ONOS
- * Update Port: Update the Port and compare it in ONOS
- * Delete Port: Delete the Port and check if it's NULL in ONOS or not
-
- * FUNCvirNetNBL3
-
- * Create Router: Post data for create Router and check it in ONOS
- * Update Router: Update the Router and compare it in ONOS
- * Delete Router: Delete the Router data and check it in ONOS
- * Create RouterInterface: Post Router Interface data to an existing Router
- and check it in ONOS
- * Delete RouterInterface: Delete the RouterInterface and check the Router
- * Create FloatingIp: Post data for create FloatingIp and check it in ONOS
- * Update FloatingIp: Update the FloatingIp and compare it in ONOS
- * Delete FloatingIp: Delete the FloatingIp and check that it is 'NULL' in
- ONOS
- * Create External Gateway: Post data to create an External Gateway for an
- existing Router and check it in ONOS
- * Update External Gateway: Update the External Gateway and compare the change
- * Delete External Gateway: Delete the External Gateway and check that it is
- 'NULL' in ONOS
-
-
Features
--------
diff --git a/docs/testing/user/userguide/test_overview.rst b/docs/testing/user/userguide/test_overview.rst
index 6aae2825..b9faa24a 100644
--- a/docs/testing/user/userguide/test_overview.rst
+++ b/docs/testing/user/userguide/test_overview.rst
@@ -86,11 +86,6 @@ validate the scenario for the release.
| | | | upstream testcases. See below |
| | | | for details |
| | +----------------+----------------------------------+
-| | | onos | Test suite of ONOS L2 and L3 |
-| | | | functions. |
-| | | | See `ONOSFW User Guide`_ for |
-| | | | details. |
-| | +----------------+----------------------------------+
| | | odl_netvirt | Test Suite for the OpenDaylight |
| | | | SDN Controller when the NetVirt |
| | | | features are installed. It |
@@ -245,7 +240,6 @@ section `Executing the functest suites`_ of this document.
.. _`[3]`: https://rally.readthedocs.org/en/latest/index.html
.. _`Doctor User Guide`: http://artifacts.opnfv.org/doctor/colorado/userguide/index.html
.. _`Promise User Guide`: http://artifacts.opnfv.org/promise/colorado/docs/userguide/index.html
-.. _`ONOSFW User Guide`: http://artifacts.opnfv.org/onosfw/colorado/userguide/index.html
.. _`SDNVPN User Guide`: http://artifacts.opnfv.org/sdnvpn/colorado/docs/userguide/index.html
.. _`Domino User Guide`: http://artifacts.opnfv.org/domino/docs/userguide-single/index.html
.. _`Parser User Guide`: http://artifacts.opnfv.org/parser/colorado/docs/userguide/index.html
diff --git a/functest/api/base.py b/functest/api/base.py
index ffc56786..75f059b7 100644
--- a/functest/api/base.py
+++ b/functest/api/base.py
@@ -45,6 +45,11 @@ class ApiResource(Resource):
return action, args
+ def _get_args(self): # pylint: disable=no-self-use
+ """ Convert the unicode to string for request.args """
+ args = api_utils.change_to_str_in_dict(request.args)
+ return args
+
def _dispatch_post(self):
""" Dispatch request """
action, args = self._post_args()
diff --git a/functest/api/resources/v1/envs.py b/functest/api/resources/v1/envs.py
index 9c455198..fb76fa63 100644
--- a/functest/api/resources/v1/envs.py
+++ b/functest/api/resources/v1/envs.py
@@ -10,11 +10,12 @@
Resources to handle environment related requests
"""
+import IPy
from flask import jsonify
from functest.api.base import ApiResource
-from functest.cli.commands.cli_env import Env
from functest.api.common import api_utils
+from functest.cli.commands.cli_env import Env
import functest.utils.functest_utils as ft_utils
@@ -38,3 +39,41 @@ class V1Envs(ApiResource):
return api_utils.result_handler(status=1, data=str(err))
return api_utils.result_handler(
status=0, data="Prepare env successfully")
+
+ def update_hosts(self, hosts_info): # pylint: disable=no-self-use
+ """ Update hosts info """
+
+ if not isinstance(hosts_info, dict):
+ return api_utils.result_handler(
+ status=1, data='Error, args should be a dict')
+
+ for key, value in hosts_info.items():
+ if key:
+ try:
+ IPy.IP(value)
+ except Exception: # pylint: disable=broad-except
+ return api_utils.result_handler(
+ status=1, data='The IP %s is invalid' % value)
+ else:
+ return api_utils.result_handler(
+ status=1, data='Domain name is absent')
+
+ try:
+ functest_flag = "# SUT hosts info for Functest"
+ hosts_list = ('\n{} {} {}'.format(ip, host_name, functest_flag)
+ for host_name, ip in hosts_info.items())
+
+ with open("/etc/hosts", 'r') as file_hosts:
+ origin_lines = [line for line in file_hosts
+ if functest_flag not in line]
+
+ with open("/etc/hosts", 'w') as file_hosts:
+ file_hosts.writelines(origin_lines)
+ file_hosts.write(functest_flag)
+ file_hosts.writelines(hosts_list)
+ except Exception: # pylint: disable=broad-except
+ return api_utils.result_handler(
+ status=1, data='Error when updating hosts info')
+ else:
+ return api_utils.result_handler(
+ status=0, data='Update hosts info successfully')
diff --git a/functest/api/resources/v1/tasks.py b/functest/api/resources/v1/tasks.py
index 7086e707..e05db51b 100644
--- a/functest/api/resources/v1/tasks.py
+++ b/functest/api/resources/v1/tasks.py
@@ -11,9 +11,10 @@
Resources to retrieve the task results
"""
-
+import errno
import json
import logging
+import os
import uuid
from flask import jsonify
@@ -21,13 +22,14 @@ from flask import jsonify
from functest.api.base import ApiResource
from functest.api.common import api_utils
from functest.api.database.v1.handlers import TasksHandler
+from functest.utils.constants import CONST
LOGGER = logging.getLogger(__name__)
-class V1Tasks(ApiResource):
- """ V1Tasks Resource class"""
+class V1Task(ApiResource):
+ """ V1Task Resource class"""
def get(self, task_id): # pylint: disable=no-self-use
""" GET the result of the task id """
@@ -56,3 +58,38 @@ class V1Tasks(ApiResource):
result = {'status': status, 'result': json.loads(task.result)}
return jsonify(result)
+
+
+class V1TaskLog(ApiResource):
+ """ V1TaskLog Resource class"""
+
+ def get(self, task_id): # pylint: disable=no-self-use
+ """ GET the log of the task id """
+ try:
+ uuid.UUID(task_id)
+ except ValueError:
+ return api_utils.result_handler(status=1, data='Invalid task id')
+
+ task_handler = TasksHandler()
+ try:
+ task = task_handler.get_task_by_taskid(task_id)
+ except ValueError:
+ return api_utils.result_handler(status=1, data='No such task id')
+
+ task_log_dir = CONST.__getattribute__('dir_results')
+
+ try:
+ with open(os.path.join(task_log_dir,
+ '{}.log'.format(task_id)), 'r') as log_file:
+ data = log_file.readlines()
+ except OSError as err:
+ if err.errno == errno.ENOENT:
+ return api_utils.result_handler(
+ status=1, data='Log file does not exist')
+
+ return api_utils.result_handler(
+ status=1, data='Error with log file')
+
+ return_data = {'data': data}
+
+ return api_utils.result_handler(status=task.status, data=return_data)
diff --git a/functest/api/resources/v1/testcases.py b/functest/api/resources/v1/testcases.py
index f146c24c..d708cf37 100644
--- a/functest/api/resources/v1/testcases.py
+++ b/functest/api/resources/v1/testcases.py
@@ -11,10 +11,12 @@
Resources to handle testcase related requests
"""
-import os
import logging
+import os
+import pkg_resources
import uuid
+import ConfigParser
from flask import abort, jsonify
from functest.api.base import ApiResource
@@ -84,6 +86,7 @@ class V1Testcase(ApiResource):
""" The built_in function to run a test case """
case_name = args.get('testcase')
+ self._update_logging_ini(args.get('task_id'))
if not os.path.isfile(CONST.__getattribute__('env_active')):
raise Exception("Functest environment is not ready.")
@@ -113,3 +116,17 @@ class V1Testcase(ApiResource):
}
return {'result': result}
+
+ def _update_logging_ini(self, task_id): # pylint: disable=no-self-use
+ """ Update the log file for each task"""
+ config = ConfigParser.RawConfigParser()
+ config.read(
+ pkg_resources.resource_filename('functest', 'ci/logging.ini'))
+ log_path = os.path.join(CONST.__getattribute__('dir_results'),
+ '{}.log'.format(task_id))
+ config.set('handler_file', 'args', '("{}",)'.format(log_path))
+
+ with open(
+ pkg_resources.resource_filename(
+ 'functest', 'ci/logging.ini'), 'wb') as configfile:
+ config.write(configfile)
diff --git a/functest/api/urls.py b/functest/api/urls.py
index f7bcae38..0cc22f80 100644
--- a/functest/api/urls.py
+++ b/functest/api/urls.py
@@ -25,8 +25,9 @@ URLPATTERNS = [
# GET /api/v1/functest/envs => GET environment
Url('/api/v1/functest/envs', 'v1_envs'),
- # POST /api/v1/functest/envs/action , {"action":"prepare"}
- # => Prepare environment
+ # POST /api/v1/functest/envs/action
+ # {"action":"prepare"} => Prepare environment
+ # {"action":"update_hosts", "args": {}} => Update hosts info
Url('/api/v1/functest/envs/action', 'v1_envs'),
# GET /api/v1/functest/openstack/credentials => GET credentials
@@ -62,5 +63,9 @@ URLPATTERNS = [
# GET /api/v1/functest/tasks/<task_id>
# => GET the result of the task id
- Url('/api/v1/functest/tasks/<task_id>', 'v1_tasks')
+ Url('/api/v1/functest/tasks/<task_id>', 'v1_task'),
+
+ # GET /api/v1/functest/tasks/<task_id>/log
+ # => GET the log of the task
+ Url('/api/v1/functest/tasks/<task_id>/log', 'v1_task_log')
]
diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml
index cf63e1ed..5ff5c824 100644
--- a/functest/ci/config_functest.yaml
+++ b/functest/ci/config_functest.yaml
@@ -6,18 +6,17 @@ general:
repo_tempest: /src/tempest
dir_repo_releng: /home/opnfv/repos/releng
repo_vims_test: /src/vims-test
- repo_onos: /home/opnfv/repos/onos
repo_barometer: /home/opnfv/repos/barometer
repo_doctor: /home/opnfv/repos/doctor
repo_odl_test: /src/odl_test
repo_fds: /src/fds
repo_securityscan: /home/opnfv/repos/securityscanning
- repo_vrouter: /home/opnfv/repos/vnfs/vrouter
functest: /home/opnfv/functest
results: /home/opnfv/functest/results
functest_conf: /home/opnfv/functest/conf
functest_data: /home/opnfv/functest/data
ims_data: /home/opnfv/functest/data/ims/
+ router_data: /home/opnfv/functest/data/router/
functest_images: /home/opnfv/functest/images
rally_inst: /root/.rally
@@ -105,11 +104,6 @@ vping:
cleanup_objects: True
unique_names: True
-onos_sfc:
- image_base_url: http://artifacts.opnfv.org/sfc/demo
- image_name: TestSfcVm
- image_file_name: firewall_block_image.img
-
odl_sfc:
image_base_url: "http://artifacts.opnfv.org/sfc/images"
image_name: sfc_nsh_danube
@@ -159,24 +153,11 @@ vnf:
tenant_name: orchestra_clearwaterims
tenant_description: Clearwater IMS deployed with Open Baton
config: orchestra.yaml
+ vyos_vrouter:
+ tenant_name: vrouter
+ tenant_description: vRouter
+ config: cloudify_vrouter.yaml
-ONOS:
- general:
- onosbench_username: 'root'
- onosbench_password: 'root'
- onoscli_username: 'root'
- onoscli_password: 'root'
- runtimeout: 300
- environment:
- OCT: '10.20.0.1'
- OC1: '10.20.0.7'
- OC2: '10.20.0.7'
- OC3: '10.20.0.7'
- OCN: '10.20.0.4'
- OCN2: '10.20.0.5'
- installer_master: '10.20.0.2'
- installer_master_username: 'root'
- installer_master_password: 'r00tme'
promise:
tenant_name: promise
tenant_description: promise Functionality Testing
diff --git a/functest/ci/download_images.sh b/functest/ci/download_images.sh
index 88474d3a..367ad8d9 100644
--- a/functest/ci/download_images.sh
+++ b/functest/ci/download_images.sh
@@ -18,8 +18,7 @@ http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-initramfs
http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-kernel
https://cloud-images.ubuntu.com/releases/14.04/release/ubuntu-14.04-server-cloudimg-arm64-uefi1.img
http://cloud.centos.org/altarch/7/images/aarch64/CentOS-7-aarch64-GenericCloud.qcow2.xz
+https://sourceforge.net/projects/ool-opnfv/files/vyos-1.1.7.img
EOF
-xz --decompress --force ${1:-/home/opnfv/functest/images}/CentOS-7-aarch64-GenericCloud.qcow2.xz
-
-exit $?
+xz --decompress --force --keep ${1:-/home/opnfv/functest/images}/CentOS-7-aarch64-GenericCloud.qcow2.xz
diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml
index ce71c9b6..5364035f 100644
--- a/functest/ci/testcases.yaml
+++ b/functest/ci/testcases.yaml
@@ -207,22 +207,6 @@ tiers:
- /src/fds/testing/robot
-
- case_name: onos
- project_name: functest
- criteria: 100
- blocking: true
- description: >-
- Test Suite for the ONOS SDN Controller. It integrates
- some test suites from upstream using TestON as the test
- framework.
- dependencies:
- installer: ''
- scenario: 'onos'
- run:
- module: 'functest.opnfv_tests.sdn.onos.onos'
- class: 'Onos'
-
- -
case_name: snaps_smoke
project_name: functest
criteria: 100
@@ -319,7 +303,7 @@ tiers:
-
case_name: functest-odl-sfc
- enabled: false
+ enabled: true
project_name: sfc
criteria: 100
blocking: false
@@ -335,21 +319,6 @@ tiers:
cmd: 'run_sfc_tests.py'
-
- case_name: onos_sfc
- enabled: false
- project_name: functest
- criteria: 100
- blocking: 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'
-
- -
case_name: parser-basics
enabled: false
project_name: parser
@@ -466,7 +435,7 @@ tiers:
-
case_name: cloudify_ims
project_name: functest
- criteria: 100
+ criteria: 80
blocking: false
description: >-
This test case deploys an OpenSource vIMS solution from Clearwater
@@ -507,15 +476,14 @@ tiers:
-
case_name: vyos_vrouter
- enabled: false
project_name: functest
criteria: 100
blocking: false
description: >-
This test case is vRouter testing.
dependencies:
- installer: 'fuel'
- scenario: 'nosdn-nofeature'
+ installer: ''
+ scenario: 'os-nosdn-nofeature-ha'
run:
- module: 'functest.opnfv_tests.vnf.router.vyos_vrouter'
- class: 'VrouterVnf'
+ module: 'functest.opnfv_tests.vnf.router.cloudify_vrouter'
+ class: 'CloudifyVrouter'
diff --git a/functest/opnfv_tests/mano/orchestra.py b/functest/opnfv_tests/mano/orchestra.py
deleted file mode 100644
index 955f82ce..00000000
--- a/functest/opnfv_tests/mano/orchestra.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-import functest.core.feature as base
-
-
-class Orchestra(base.Feature):
- def __init__(self, **kwargs):
- if "project_name" not in kwargs:
- kwargs["project_name"] = "orchestra"
- if "case_name" not in kwargs:
- kwargs["case_name"] = "orchestra"
- kwargs['repo'] = 'dir_repo_orchestra'
- super(Orchestra, self).__init__(**kwargs)
- # TODO
- # self.cmd = "%s/tests/run.sh %s/tests" % (self.repo, self.repo)
diff --git a/functest/opnfv_tests/openstack/rally/blacklist.txt b/functest/opnfv_tests/openstack/rally/blacklist.txt
index 099d6864..0623368d 100644
--- a/functest/opnfv_tests/openstack/rally/blacklist.txt
+++ b/functest/opnfv_tests/openstack/rally/blacklist.txt
@@ -38,6 +38,16 @@ scenario:
# Bug: https://bugs.launchpad.net/ubuntu/+bug/1704138
# Fix: https://review.openstack.org/#/c/483402/
- CeilometerEvents.create_user_and_list_event_types
+ -
+ scenarios:
+ - '^os-' # all scenarios
+ installers:
+ - '.+' # all installers
+ tests:
+ # Starting from ocata, following tests require the presence of
+ # panko in the deployment. This is not currently fulfilled
+ # Ref: https://docs.openstack.org/releasenotes/ceilometer/ocata.html
+ - 'CeilometerEvents..*'
functionality:
-
diff --git a/functest/opnfv_tests/openstack/refstack_client/refstack_client.py b/functest/opnfv_tests/openstack/refstack_client/refstack_client.py
index 4f71b5f5..17e02466 100644
--- a/functest/opnfv_tests/openstack/refstack_client/refstack_client.py
+++ b/functest/opnfv_tests/openstack/refstack_client/refstack_client.py
@@ -100,6 +100,14 @@ class RefstackClient(testcase.TestCase):
try:
with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
"refstack.log"), 'r') as logfile:
+ for line in logfile.readlines():
+ if 'Tests' in line:
+ break
+ if re.search(r"\} tempest\.", line):
+ LOGGER.info(line.replace('\n', ''))
+
+ with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
+ "refstack.log"), 'r') as logfile:
output = logfile.read()
for match in re.findall(r"Ran: (\d+) tests in (\d+\.\d{4}) sec.",
@@ -216,11 +224,14 @@ class RefstackClient(testcase.TestCase):
if not self.tempestconf:
self.generate_conf()
- os_utils.init_tempest_cleanup(
- self.tempestconf.DEPLOYMENT_DIR, 'tempest.conf',
- os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
- "tempest-cleanup-init.log")
- )
+ try:
+ os_utils.init_tempest_cleanup(
+ self.tempestconf.DEPLOYMENT_DIR, 'tempest.conf',
+ os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
+ "tempest-cleanup-init.log"))
+ except Exception as err:
+ LOGGER.error(str(err))
+ return testcase.TestCase.EX_RUN_ERROR
return super(RefstackClient, self).create_snapshot()
diff --git a/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py b/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py
index 19c6a87f..bfdcd862 100644
--- a/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py
+++ b/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py
@@ -10,7 +10,6 @@ import logging
from functest.core import unit
from functest.opnfv_tests.openstack.snaps import snaps_utils
-from functest.utils import functest_utils
from functest.utils.constants import CONST
from snaps.openstack import create_flavor
@@ -44,7 +43,7 @@ class SnapsTestRunner(unit.Suite):
self.use_fip = CONST.__getattribute__('snaps_use_floating_ips')
self.use_keystone = CONST.__getattribute__('snaps_use_keystone')
- scenario = functest_utils.get_scenario()
+ scenario = CONST.__getattribute__('DEPLOY_SCENARIO')
self.flavor_metadata = None
if 'ovs' in scenario or 'fdio' in scenario:
diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py
index c7ad4df2..b8a4e9ad 100644
--- a/functest/opnfv_tests/openstack/tempest/tempest.py
+++ b/functest/opnfv_tests/openstack/tempest/tempest.py
@@ -267,11 +267,14 @@ class TempestCommon(testcase.TestCase):
# Make sure that the verifier is configured
conf_utils.configure_verifier(self.DEPLOYMENT_DIR)
- os_utils.init_tempest_cleanup(
- self.DEPLOYMENT_DIR, 'tempest.conf',
- os.path.join(conf_utils.TEMPEST_RESULTS_DIR,
- "tempest-cleanup-init.log")
- )
+ try:
+ os_utils.init_tempest_cleanup(
+ self.DEPLOYMENT_DIR, 'tempest.conf',
+ os.path.join(conf_utils.TEMPEST_RESULTS_DIR,
+ "tempest-cleanup-init.log"))
+ except Exception as err:
+ logger.error(str(err))
+ return testcase.TestCase.EX_RUN_ERROR
return super(TempestCommon, self).create_snapshot()
@@ -442,7 +445,7 @@ class TempestResourcesManager(object):
if (CONST.__getattribute__('tempest_use_custom_flavors') or
use_custom_flavors):
logger.info("Creating flavor for Tempest suite")
- scenario = ft_utils.get_scenario()
+ scenario = CONST.__getattribute__('DEPLOY_SCENARIO')
flavor_metadata = None
if 'ovs' in scenario or 'fdio' in scenario:
flavor_metadata = create_flavor.MEM_PAGE_SIZE_LARGE
@@ -461,7 +464,7 @@ class TempestResourcesManager(object):
if use_custom_flavors:
logger.info("Creating 2nd flavor for Tempest suite")
- scenario = ft_utils.get_scenario()
+ scenario = CONST.__getattribute__('DEPLOY_SCENARIO')
flavor_metadata_alt = None
if 'ovs' in scenario or 'fdio' in scenario:
flavor_metadata_alt = create_flavor.MEM_PAGE_SIZE_LARGE
diff --git a/functest/opnfv_tests/openstack/vping/vping_base.py b/functest/opnfv_tests/openstack/vping/vping_base.py
index 6e908065..c93d2f26 100644
--- a/functest/opnfv_tests/openstack/vping/vping_base.py
+++ b/functest/opnfv_tests/openstack/vping/vping_base.py
@@ -13,7 +13,6 @@ import time
import uuid
from functest.core import testcase
-from functest.utils import functest_utils
from functest.utils.constants import CONST
from snaps.openstack import create_flavor
@@ -139,7 +138,7 @@ class VPingBase(testcase.TestCase):
self.logger.info(
"Creating flavor with name: '%s'" % self.flavor_name)
- scenario = functest_utils.get_scenario()
+ scenario = CONST.__getattribute__('DEPLOY_SCENARIO')
flavor_metadata = None
if 'ovs' in scenario or 'fdio' in scenario:
flavor_metadata = create_flavor.MEM_PAGE_SIZE_LARGE
diff --git a/functest/opnfv_tests/sdn/onos/onos.py b/functest/opnfv_tests/sdn/onos/onos.py
deleted file mode 100644
index 08ba4da3..00000000
--- a/functest/opnfv_tests/sdn/onos/onos.py
+++ /dev/null
@@ -1,232 +0,0 @@
-#!/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 logging
-import os
-import pkg_resources
-import re
-import subprocess
-import shutil
-import time
-import urlparse
-
-from functest.core import testcase
-from functest.utils.constants import CONST
-import functest.utils.functest_utils as ft_utils
-import functest.utils.openstack_utils as openstack_utils
-
-
-class OnosBase(testcase.TestCase):
- onos_repo_path = CONST.__getattribute__('dir_repo_onos')
- onos_sfc_image_name = CONST.__getattribute__('onos_sfc_image_name')
- onos_sfc_image_path = os.path.join(
- CONST.__getattribute__('dir_functest_images'),
- CONST.__getattribute__('onos_sfc_image_file_name'))
- onos_sfc_path = pkg_resources.resource_filename(
- 'functest', 'opnfv_tests/sdn/onos/sfc')
- installer_type = CONST.__getattribute__('INSTALLER_TYPE')
- logger = logging.getLogger(__name__)
-
- def __init__(self, **kwargs):
- if "case_name" not in kwargs:
- kwargs["case_name"] = "onos_base"
- super(OnosBase, self).__init__(**kwargs)
-
- def run(self):
- self.start_time = time.time()
- try:
- self._run()
- res = testcase.TestCase.EX_OK
- except Exception as e:
- self.logger.error('Error with run: %s', e)
- res = testcase.TestCase.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, **kwargs):
- if "case_name" not in kwargs:
- kwargs["case_name"] = "onos"
- super(Onos, self).__init__(**kwargs)
- self.log_path = os.path.join(self.onos_repo_path, 'TestON/logs')
-
- def set_onos_ip(self):
- if (self.installer_type and
- self.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
- self.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)
- self.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:
- self.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:
- self.logger.debug(line)
- if re.search("\s+[1-9]+\s+", line):
- self.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 Exception:
- self.logger.error("Unable to set ONOS result")
-
- self.result = 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, **kwargs):
- if "case_name" not in kwargs:
- kwargs["case_name"] = "onos_sfc"
- super(OnosSfc, self).__init__(**kwargs)
-
- def get_ip(self, type):
- url = openstack_utils.get_endpoint(service_type=type)
- self.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):
- self.logger.warn('inside create_image')
- 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')
-
- self.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("identity"))
- self.update_sfc_onos_file("neutron_ip", self.get_ip("network"))
- self.update_sfc_onos_file("nova_ip", self.get_ip("compute"))
- self.update_sfc_onos_file("glance_ip", self.get_ip("image"))
- self.update_sfc_onos_file("console",
- CONST.__getattribute__('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)
- self.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/sfc/README.md b/functest/opnfv_tests/sdn/onos/sfc/README.md
deleted file mode 100644
index ae63ee21..00000000
--- a/functest/opnfv_tests/sdn/onos/sfc/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-SFC Script ReadMe File
-**********************
-
-Topology
----------
-
-Validated with the Fuel Enviroment.
-
-
-Things to Remember :
---------------------
-
-1] This Script basically Tests the SFC functionality with ONOS controller.
-2] Ip address of Openstack and ONOS are got dynamically.
-3] Initally this sfc script can be used for ONOS and on Request , if need will modify for other controllers.
-
-
-Contact Details :
------------------
-
-email-id : antonysilvester@gmail.com
diff --git a/functest/opnfv_tests/sdn/onos/sfc/sfc.py b/functest/opnfv_tests/sdn/onos/sfc/sfc.py
deleted file mode 100644
index 2bb9082c..00000000
--- a/functest/opnfv_tests/sdn/onos/sfc/sfc.py
+++ /dev/null
@@ -1,174 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) CREATED5 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
-#
-# ###########################################################################
-# OPNFV SFC Script
-# **** Scripted by Antony Silvester - antony.silvester@huawei.com ******
-# ###########################################################################
-
-# Testcase 1 : Prerequisites configuration for SFC
-# Testcase 2 : Creation of 3 VNF Nodes and Attaching Ports
-# Testcase 3 : Configure SFC [Port pair,Port Group ,Flow classifer
-# Testcase 4 : Configure Port Chain and verify the flows are added.
-# Testcase 5 : Verify traffic with VNF node.
-# Testcase 6 : Remove the Port Chain and Verify the traffic.
-# Testcase 7 : Cleanup
-# ###########################################################################
-#
-"""Script to Test the SFC scenarios in ONOS."""
-
-import logging
-import time
-import functest.utils.functest_utils as ft_utils
-from sfc_onos import SfcOnos
-
-logger = logging.getLogger(__name__)
-Sfc_obj = SfcOnos()
-
-OK = 200
-CREATED = 201
-ACCEPTED = 202
-NO_CONTENT = 204
-
-start_time = time.time()
-
-
-def PreConfig():
- logger.info("Testcase 1 : Prerequisites configuration for SFC")
- logger.info("1.1 Creation of Auth-Token")
- check(Sfc_obj.getToken, OK, "Creation of Token")
- logger.info("1.2 Creation of Network")
- check(Sfc_obj.createNetworks, CREATED, "Creation of network")
- logger.info("1.3 Creation of Subnetwork")
- check(Sfc_obj.createSubnets, CREATED, "Creation of Subnetwork")
-
-
-def CreateNodes():
- logger.info("Testcase 2 : Creation of 3 VNF Nodes and Attaching Ports")
- logger.info("2.1 Creation of Ports")
- check(Sfc_obj.createPorts, CREATED, "Creation of Port")
- logger.info("2.2 Creation of VM-Compute-Node")
- check(Sfc_obj.createVm, ACCEPTED, "Creation of VM")
- logger.info("2.3 Check VM Status")
- check(Sfc_obj.checkVmState, OK, "Vm statue check")
- logger.info("2.4 Router Creation")
- check(Sfc_obj.createRouter, CREATED, "Creation of Router")
- logger.info("2.5 Attachement of Interface to VM")
- check(Sfc_obj.attachInterface, OK, "Interface attached to VM")
- logger.info("2.6 Attachement of FLoating Ip to VM")
- check(Sfc_obj.addFloatingIp, ACCEPTED, "Floating Ip attached to VM")
-
-
-def ConfigSfc():
- logger.info(
- "Testcase 3 : Configure SFC [Portair,PortGroup,Flow classifer]")
- logger.info("3.1 Creation of Port Pair")
- check(Sfc_obj.createPortPair, CREATED, "Creation of Port Pair")
- logger.info("3.2 Getting the Port Pair ID")
- check(Sfc_obj.getPortPair, OK, "Getting Port Pair ID")
- logger.info("3.3 Creation of Port Pair Group")
- check(Sfc_obj.createPortGroup, CREATED, "Creation of Port Pair Group")
- logger.info("3.4 Getting Port Pair Group ID ")
- check(Sfc_obj.getPortGroup, OK, "Getting Port Pair Group ID")
- logger.info("3.5 Creation of Flow Classifier")
- check(Sfc_obj.createFlowClassifier, CREATED, "Creation of Flow Classifier")
- logger.info(
- "Testcase 4 : Configure Port Chain and verify flows are added")
- logger.info("4.1 Creation of Port Chain")
- check(Sfc_obj.createPortChain, CREATED, "Creation of Port Chain")
-
-
-def VerifySfcTraffic():
- status = "PASS"
- logger.info("Testcase 5 : Verify traffic with VNF node.")
- if (Sfc_obj.loginToVM() == "1"):
- logger.info("SFC function Working")
- else:
- logger.error("SFC function not working")
- status = "FAIL"
-
- logger.info("Testcase 6 : Remove the Port Chain and Verify the traffic")
- if (Sfc_obj.deletePortChain() == NO_CONTENT):
- if (Sfc_obj.loginToVM() == "0"):
- logger.info("SFC function is removed Successfully")
- else:
- logger.error("SFC function not Removed. Have some problem")
- status = "FAIL"
- if (Sfc_obj.deleteFlowClassifier() == NO_CONTENT):
- if (Sfc_obj.deletePortGroup() == NO_CONTENT):
- if (Sfc_obj.deletePortPair() == NO_CONTENT):
- logger.info(
- "SFC configuration is deleted successfully")
- else:
- logger.error("Port pair is deleted successfully")
- status = "FAIL"
- else:
- logger.error("Port Group is NOT deleted successfully")
- status = "FAIL"
- else:
- logger.error("Flow classifier is NOT deleted successfully")
- status = "FAIL"
- else:
- logger.error("PortChain configuration is NOT deleted successfully")
- status = "FAIL"
- if (status == "FAIL"):
- fail("Traffic for SFC is NOT verified successfully")
-
-
-def CleanUp():
- logger.info("Testcase 7 : Cleanup")
- if (Sfc_obj.cleanup() == NO_CONTENT):
- logger.info("CleanUp is successfull")
- else:
- logger.error("CleanUp is NOT successfull")
-
-
-def check(method, criteria, msg):
- if (method() == criteria):
- logger.info(msg + 'is Successful')
- else:
- fail(msg + 'is not successful')
-
-
-def fail(fail_info):
- logger.error(fail_info)
- CleanUp()
- PushDB("FAIL", fail_info)
- exit(-1)
-
-
-def PushDB(status, info):
- logger.info("Summary :")
- try:
- logger.debug("Push ONOS SFC results into DB")
- stop_time = time.time()
-
- # ONOS SFC success criteria = all tests OK
- duration = round(stop_time - start_time, 1)
- logger.info("Result is " + status)
- ft_utils.push_results_to_db("functest",
- "onos_sfc",
- start_time,
- stop_time,
- status,
- details={'duration': duration,
- 'error': info})
- except:
- logger.error("Error pushing results into Database")
-
-
-def main():
- """Script to Test the SFC scenarios in ONOS."""
- logging.basicConfig()
- PreConfig()
- CreateNodes()
- ConfigSfc()
- VerifySfcTraffic()
- CleanUp()
- PushDB("PASS", "")
diff --git a/functest/opnfv_tests/sdn/onos/sfc/sfc_onos.py b/functest/opnfv_tests/sdn/onos/sfc/sfc_onos.py
deleted file mode 100644
index 4e93c133..00000000
--- a/functest/opnfv_tests/sdn/onos/sfc/sfc_onos.py
+++ /dev/null
@@ -1,887 +0,0 @@
-import logging
-import os
-import re
-import time
-import json
-import requests
-
-from multiprocessing import Process
-from multiprocessing import Queue
-from pexpect import pxssh
-
-from functest.utils.constants import CONST
-
-OK = 200
-CREATED = 201
-ACCEPTED = 202
-NO_CONTENT = 204
-
-
-class SfcOnos(object):
- """Defines all the def function of SFC."""
-
- def __init__(self):
- """Initialization of variables."""
- self.logger = logging.getLogger(__name__)
- self.osver = "v2.0"
- self.token_id = 0
- self.net_id = 0
- self.image_id = 0
- self.keystone_hostname = 'keystone_ip'
- self.neutron_hostname = 'neutron_ip'
- self.nova_hostname = 'nova_ip'
- self.glance_hostname = 'glance_ip'
- self.onos_hostname = 'onos_ip'
- # Network variables #######
- self.netname = "test_nw"
- self.admin_state_up = True
- self.tenant_id = 0
- self.subnetId = 0
- # #########################
- # SubNet variables#########
- self.ip_version = 4
- self.cidr = "20.20.20.0/24"
- self.subnetname = "test_nw_subnets"
- # ###############################
- # Port variable
- self.port = "port"
- self.port_num = []
- self.vm_id = 0
- self.port_ip = []
- self.count = 0
- self.i = 0
- self.numTerms = 3
- self.security_groups = []
- self.port_security_enabled = False
- # ###############################
- # VM creation variable
- self.container_format = "bare"
- self.disk_format = "qcow2"
- self.imagename = "TestSfcVm"
- self.createImage = ("/home/root1/devstack/files/images/"
- "firewall_block_image.img")
-
- self.vm_name = "vm"
- self.imageRef = "test"
- self.flavorRef = "1"
- self.max_count = "1"
- self.min_count = "1"
- self.org_nw_port = []
- self.image_id = 0
- self.routername = "router1"
- self.router_id = 0
- # #####################################
- # Port pair
- self.port_pair_ingress = 0
- self.port_pair_egress = 0
- self.port_pair_name = "PP"
- self.port_pair_id = []
- # ####################################
- # Port Group
- self.port_group_name = "PG"
- self.port_grp_id = []
- # ####################################
- # FlowClassifier
- self.source_ip_prefix = "20.20.20.0/24"
- self.destination_ip_prefix = "20.20.20.0/24"
- self.logical_source_port = 0
- self.fcname = "FC"
- self.ethertype = "IPv4"
- # #####################################
- self.flow_class_if = 0
- # #####################################
- # Port Chain variables
- self.pcname = 'PC'
- self.PC_id = 0
- # #####################################
- # Port Chain variables
- self.flowadd = ''
- # #####################################
- self.ip_pool = 0
- self.vm_public_ip = []
- self.vm_public_id = []
- self.cirros_username = CONST.__getattribute__(
- 'openstack_image_username')
- self.cirros_password = CONST.__getattribute__(
- 'openstack_image_password')
- self.net_id1 = 0
- self.vm = []
- self.address = 0
- self.value = 0
- self.pub_net_id = 0
-
- def getToken(self):
- """Get the keystone token value from Openstack ."""
- url = 'http://%s:5000/%s/tokens' % (self.keystone_hostname,
- self.osver)
- data = ('{"auth": {"tenantName": "admin", "passwordCredentials":'
- '{ "username": "admin", "password": "console"}}}')
- headers = {"Accept": "application/json"}
- response = requests.post(url, headers=headers, data=data)
- if (response.status_code == OK):
- json1_data = json.loads(response.content)
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- self.logger.debug(json1_data)
- self.token_id = json1_data['access']['token']['id']
- self.tenant_id = json1_data['access']['token']['tenant']['id']
- return(response.status_code)
- else:
- return(response.status_code)
-
- def createNetworks(self):
- """Creation of networks."""
- Dicdata = {}
- if self.netname != '':
- Dicdata['name'] = self.netname
- if self.admin_state_up != '':
- Dicdata['admin_state_up'] = self.admin_state_up
- Dicdata = {'network': Dicdata}
- data = json.dumps(Dicdata, indent=4)
- url = 'http://%s:9696/%s/networks' % (self.neutron_hostname,
- self.osver)
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.post(url, headers=headers, data=data)
- if (response.status_code == CREATED):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
-
- json1_data = json.loads(response.content)
- self.logger.debug(json1_data)
- self.net_id = json1_data['network']['id']
- return(response.status_code)
- else:
- return(response.status_code)
-
- def createSubnets(self):
- """Creation of SubNets."""
- Dicdata = {}
- if self.net_id != 0:
- Dicdata['network_id'] = self.net_id
- if self.ip_version != '':
- Dicdata['ip_version'] = self.ip_version
- if self.cidr != '':
- Dicdata['cidr'] = self.cidr
- if self.subnetname != '':
- Dicdata['name'] = self.subnetname
-
- Dicdata = {'subnet': Dicdata}
- data = json.dumps(Dicdata, indent=4)
- url = 'http://%s:9696/%s/subnets' % (self.neutron_hostname,
- self.osver)
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.post(url, headers=headers, data=data)
-
- if (response.status_code == CREATED):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- json1_data = json.loads(response.content)
- self.logger.debug(json1_data)
- self.subnetId = json1_data['subnet']['id']
- return(response.status_code)
- else:
- return(response.status_code)
-
- def createPorts(self):
- """Creation of Ports."""
- for x in range(self.i, self.numTerms):
- Dicdata = {}
- if self.net_id != '':
- Dicdata['network_id'] = self.net_id
- if self.port != '':
- Dicdata['name'] = "port" + str(x)
- if self.admin_state_up != '':
- Dicdata['admin_state_up'] = self.admin_state_up
- if self.security_groups != '':
- Dicdata['security_groups'] = self.security_groups
- # if self.port_security_enabled != '':
- # Dicdata['port_security_enabled'] = self.port_security_enabled
-
- Dicdata = {'port': Dicdata}
- data = json.dumps(Dicdata, indent=4)
- url = 'http://%s:9696/%s/ports' % (self.neutron_hostname,
- self.osver)
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.post(url, headers=headers, data=data)
-
- if (response.status_code == CREATED):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
-
- json1_data = json.loads(response.content)
- self.logger.debug(json1_data)
- self.port_num.append(json1_data['port']['id'])
- self.port_ip.append(json1_data['port']['fixed_ips'][0]
- ['ip_address'])
- else:
- return(response.status_code)
- return(response.status_code)
-
- def createVm(self):
- """Creation of Instance, using firewall image."""
- url = ("http://%s:9292/v2/images?"
- "name=TestSfcVm" % (self.glance_hostname))
- headers = {"Accept": "application/json",
- "Content-Type": "application/octet-stream",
- "X-Auth-Token": self.token_id}
- response = requests.get(url, headers=headers)
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- self.logger.info("FireWall Image is available")
- json1_data = json.loads(response.content)
- self.logger.debug(json1_data)
- self.image_id = json1_data['images'][0]['id']
- else:
- return(response.status_code)
-
- url = ("http://%s:8774/v2.1/%s/flavors?"
- "name=m1.tiny" % (self.nova_hostname, self.tenant_id))
- headers = {"Accept": "application/json", "Content-Type":
- "application/json", "X-Auth-Token": self.token_id}
- response = requests.get(url, headers=headers)
-
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- self.logger.info("Flavor is available")
- json1_data = json.loads(response.content)
- self.logger.debug(json1_data)
- self.flavorRef = json1_data['flavors'][0]['id']
- else:
- return(response.status_code)
-
- for y in range(0, 3):
- Dicdata = {}
- org_nw_port = []
- org_nw_port.append({'port': self.port_num[y]})
- if self.vm_name != '':
- Dicdata['name'] = "vm" + str(y)
- if self.imageRef != '':
- Dicdata['imageRef'] = self.image_id
- if self.flavorRef != '':
- Dicdata['flavorRef'] = self.flavorRef
- if self.max_count != '':
- Dicdata['max_count'] = self.max_count
- if self.min_count != '':
- Dicdata['min_count'] = self.min_count
- if self.org_nw_port != '':
- Dicdata['networks'] = org_nw_port
- Dicdata = {'server': Dicdata}
- data = json.dumps(Dicdata, indent=4)
- url = 'http://%s:8774/v2.1/%s/servers' % (self.nova_hostname,
- self.tenant_id)
- headers = {"Accept": "application/json", "Content-Type":
- "application/json", "X-Auth-Token": self.token_id}
- response = requests.post(url, headers=headers, data=data)
- if (response.status_code == ACCEPTED):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- info = "Creation of VM" + str(y) + " is successfull"
- self.logger.debug(info)
-
- json1_data = json.loads(response.content)
- self.logger.debug(json1_data)
- self.vm_id = json1_data['server']['id']
- self.vm.append(json1_data['server']['id'])
- else:
- return(response.status_code)
-
- return(response.status_code)
-
- def checkVmState(self):
- """Checking the Status of the Instance."""
- time.sleep(10)
- for y in range(0, 3):
- url = ("http://%s:8774/v2.1/servers/"
- "detail?name=vm" + str(y)) % (self.neutron_hostname)
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.get(url, headers=headers)
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- json1_data = json.loads(response.content)
- self.logger.debug(json1_data)
- self.vm_active = json1_data['servers'][0]['status']
- if (self.vm_active == "ACTIVE"):
- info = "VM" + str(y) + " is Active : " + self.vm_active
- else:
- info = "VM" + str(y) + " is NOT Active : " + self.vm_active
- self.logger.debug(info)
- else:
- return(response.status_code)
- return(response.status_code)
- time.sleep(10)
-
- def createPortPair(self):
- """Creation of Port Pair."""
- for p in range(1, 2):
- Dicdata = {}
- if self.port_pair_ingress != '':
- Dicdata['ingress'] = self.port_num[p]
- if self.port_pair_egress != '':
- egress = p
- Dicdata['egress'] = self.port_num[egress]
- if self.port_pair_name != '':
- Dicdata['name'] = "PP" + str(p)
-
- Dicdata = {'port_pair': Dicdata}
- data = json.dumps(Dicdata, indent=4)
- url = 'http://%s:9696/%s/sfc/port_pairs' % (self.neutron_hostname,
- self.osver)
- headers = {"Accept": "application/json", "X-Auth-Token":
- self.token_id}
- response = requests.post(url, headers=headers, data=data)
- if (response.status_code == CREATED):
- info = ("Creation of Port Pair PP" + str(p) +
- " is successful")
- self.logger.debug(info)
- else:
- return(response.status_code)
-
- return(response.status_code)
-
- def getPortPair(self):
- """Query the Portpair id value."""
- for p in range(0, 1):
- url = ("http://%s:9696/%s/"
- "sfc/port_pairs?name=PP1" % (self.neutron_hostname,
- self.osver))
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.get(url, headers=headers)
-
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- json1_data = json.loads(response.content)
- self.logger.debug(json1_data)
- self.port_pair_id.append(json1_data['port_pairs'][0]['id'])
- else:
- return(response.status_code)
- return(response.status_code)
-
- def createPortGroup(self):
- """Creation of PortGroup."""
- for p in range(0, 1):
- Dicdata = {}
- port_pair_list = []
- port_pair_list.append(self.port_pair_id[p])
- if self.port_group_name != '':
- Dicdata['name'] = "PG" + str(p)
- if self.port_pair_id != '':
- Dicdata['port_pairs'] = port_pair_list
-
- Dicdata = {'port_pair_group': Dicdata}
- data = json.dumps(Dicdata, indent=4)
- url = ("http://%s:9696/%s/"
- "sfc/port_pair_groups" % (self.neutron_hostname,
- self.osver))
- headers = {"Accept": "application/json", "X-Auth-Token":
- self.token_id}
- response = requests.post(url, headers=headers, data=data)
- if (response.status_code == CREATED):
- info = ("Creation of Port Group PG" + str(p) +
- "is successful")
- self.logger.debug(info)
- else:
- return(response.status_code)
-
- return(response.status_code)
-
- def getPortGroup(self):
- """Query the PortGroup id."""
- for p in range(0, 1):
- url = ("http://%s:9696/%s/sfc/port_pair_groups"
- "?name=PG" + str(p)) % (self.neutron_hostname,
- self.osver)
- headers = {"Accept": "application/json", "X-Auth-Token":
- self.token_id}
- response = requests.get(url, headers=headers)
-
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- json1_data = json.loads(response.content)
- self.port_grp_id.append(json1_data['port_pair_groups']
- [0]['id'])
- else:
- return(response.status_code)
- return(response.status_code)
-
- def createFlowClassifier(self):
- """Creation of Flow Classifier."""
- Dicdata = {}
- if self.source_ip_prefix != '':
- Dicdata['source_ip_prefix'] = self.source_ip_prefix
- if self.destination_ip_prefix != '':
- Dicdata['destination_ip_prefix'] = self.destination_ip_prefix
- if self.logical_source_port != '':
- Dicdata['logical_source_port'] = self.port_num[0]
- if self.fcname != '':
- Dicdata['name'] = "FC1"
- if self.ethertype != '':
- Dicdata['ethertype'] = self.ethertype
-
- Dicdata = {'flow_classifier': Dicdata}
- data = json.dumps(Dicdata, indent=4)
- url = ("http://%s:9696/%s/"
- "sfc/flow_classifiers" % (self.neutron_hostname,
- self.osver))
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.post(url, headers=headers, data=data)
- if (response.status_code == CREATED):
- json1_data = json.loads(response.content)
- self.flow_class_if = json1_data['flow_classifier']['id']
- self.logger.debug("Creation of Flow Classifier is successful")
- return(response.status_code)
- else:
- return(response.status_code)
-
- def createPortChain(self):
- """Creation of PortChain."""
- Dicdata = {}
- flow_class_list = []
- flow_class_list.append(self.flow_class_if)
- port_pair_groups_list = []
- port_pair_groups_list.append(self.port_grp_id[0])
-
- if flow_class_list != '':
- Dicdata['flow_classifiers'] = flow_class_list
- if self.pcname != '':
- Dicdata['name'] = "PC1"
- if port_pair_groups_list != '':
- Dicdata['port_pair_groups'] = port_pair_groups_list
-
- Dicdata = {'port_chain': Dicdata}
- data = json.dumps(Dicdata, indent=4)
- url = 'http://%s:9696/%s/sfc/port_chains' % (self.neutron_hostname,
- self.osver)
- headers = {"Accept": "application/json",
- "Content-Type": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.post(url, headers=headers, data=data)
- if (response.status_code == CREATED):
- self.logger.debug("Creation of PORT CHAIN is successful")
- json1_data = json.loads(response.content)
- self.PC_id = json1_data['port_chain']['id']
- return(response.status_code)
- else:
- return(response.status_code)
-
- def checkFlowAdded(self):
- """Check whether the Flows are downloaded successfully."""
- time.sleep(5)
- response = requests.get('http://' + self.onos_hostname +
- ':8181/onos/v1/flows',
- auth=("karaf", "karaf"))
- if (response.status_code == OK):
- self.logger.debug("Flow is successfully Queries")
- json1_data = json.loads(response.content)
- self.flowadd = json1_data['flows'][0]['state']
-
- if (self.flowadd == "ADDED"):
- self.logger.info("Flow is successfully added to OVS")
- return(response.status_code)
- else:
- return(404)
- else:
- return(response.status_code)
-####################################################################
-
- def createRouter(self):
- """Creation of Router."""
- Dicdata = {}
- if self.routername != '':
- Dicdata['name'] = "router1"
- if self.admin_state_up != '':
- Dicdata['admin_state_up'] = self.admin_state_up
-
- Dicdata = {'router': Dicdata}
- data = json.dumps(Dicdata, indent=4)
- url = 'http://%s:9696/%s/routers.json' % (self.neutron_hostname,
- self.osver)
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.post(url, headers=headers, data=data)
- if (response.status_code == CREATED):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- self.logger.debug("Creation of Router is successfull")
- json1_data = json.loads(response.content)
- self.logger.debug(json1_data)
- self.router_id = json1_data['router']['id']
- return(response.status_code)
- else:
- return(response.status_code)
-
- def attachInterface(self):
- """Attachment of instance ports to the Router."""
- url = ("http://%s:9696/%s/networks"
- "?name=admin_floating_net" % (self.neutron_hostname,
- self.osver))
- headers = {"Accept": "application/json", "X-Auth-Token": self.token_id}
- response = requests.get(url, headers=headers)
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- json1_data = json.loads(response.content)
- self.logger.debug(json1_data)
- self.net_name = json1_data['networks'][0]['name']
- if (self.net_name == "admin_floating_net"):
- self.pub_net_id = json1_data['networks'][0]['id']
- else:
- return(response.status_code)
- ############################################################
-
- self.logger.info("Attachment of Instance interface to Router")
- Dicdata = {}
- if self.subnetId != '':
- Dicdata['subnet_id'] = self.subnetId
-
- data = json.dumps(Dicdata, indent=4)
- url = ("http://%s:9696/%s/routers"
- "/%s/add_router_interface" % (self.neutron_hostname,
- self.osver,
- self.router_id))
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.put(url, headers=headers, data=data)
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- self.logger.info("Interface attached successfull")
- else:
- return(response.status_code)
- ############################################################
- self.logger.info("Attachment of Gateway to Router")
-
- Dicdata1 = {}
- if self.pub_net_id != 0:
- Dicdata1['network_id'] = self.pub_net_id
-
- Dicdata1 = {'external_gateway_info': Dicdata1}
- Dicdata1 = {'router': Dicdata1}
- data = json.dumps(Dicdata1, indent=4)
- url = 'http://%s:9696/%s/routers/%s' % (self.neutron_hostname,
- self.osver,
- self.router_id)
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.put(url, headers=headers, data=data)
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- self.logger.info("Gateway Interface attached successfull")
- return(response.status_code)
- else:
- return(response.status_code)
-
- def addFloatingIp(self):
- """Attachment of Floating Ip to the Router."""
- for ip_num in range(0, 2):
- Dicdata = {}
- Dicdata['pool'] = "admin_floating_net"
-
- data = json.dumps(Dicdata, indent=4)
- url = ("http://%s:8774/v2.1/"
- "os-floating-ips" % (self.nova_hostname))
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.post(url, headers=headers, data=data)
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- self.logger.info("Floating ip created successfully")
- json1_data = json.loads(response.content)
- self.logger.debug(json1_data)
- self.vm_public_ip.append(json1_data['floating_ip']['ip'])
- self.vm_public_id.append(json1_data['floating_ip']['id'])
- else:
- self.logger.error("Floating ip NOT created successfully")
-
- Dicdata1 = {}
- if self.address != '':
- Dicdata1['address'] = self.vm_public_ip[ip_num]
-
- Dicdata1 = {'addFloatingIp': Dicdata1}
- data = json.dumps(Dicdata1, indent=4)
- url = ("http://%s:8774/v2.1/"
- "servers/%s/action" % (self.nova_hostname,
- self.vm[ip_num]))
-
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.post(url, headers=headers, data=data)
- if(response.status_code == ACCEPTED):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- self.logger.info("Public Ip successfully added to VM")
- else:
- return(response.status_code)
- return(response.status_code)
-
- def loginToVM(self):
- """Login to the VM to check NSH packets are received."""
- queue1 = "0"
-
- def vm0():
-
- s = pxssh.pxssh()
- hostname = self.vm_public_ip[0]
- s.login(hostname, self.cirros_username, self.cirros_password)
- s.sendline("ping -c 5 " + str(self.port_ip[2]))
- s.prompt() # match the prompt
-
- ping_re = re.search("transmitted.*received", s.before).group()
- x = re.split('\s+', ping_re)
- if (x[1] >= "1"):
- self.logger.info("Ping is Successfull")
- else:
- self.logger.info("Ping is NOT Successfull")
-
- def vm1(queue1):
- s = pxssh.pxssh()
- hostname = self.vm_public_ip[1]
- s.login(hostname, self.cirros_username, self.cirros_password)
- s.sendline('sudo ./firewall')
- s.prompt()
- output_pack = s.before
-
- if(output_pack.find("nshc") != -1):
- self.logger.info("The packet has reached VM2 Instance")
- queue1.put("1")
- else:
- self.logger.info("Packet not received in Instance")
- queue1.put("0")
-
- def ping(ip, timeout=300):
- while True:
- time.sleep(1)
- self.logger.debug("Pinging %s. Waiting for response..." % ip)
- response = os.system("ping -c 1 " + ip + " >/dev/null 2>&1")
- if response == 0:
- self.logger.info("Ping " + ip + " detected!")
- return 0
-
- elif timeout == 0:
- self.logger.info("Ping " + ip + " timeout reached.")
- return 1
- timeout -= 1
-
- result0 = ping(self.vm_public_ip[0])
- result1 = ping(self.vm_public_ip[1])
- if result0 == 0 and result1 == 0:
- time.sleep(300)
- queue1 = Queue()
- p1 = Process(target=vm1, args=(queue1, ))
- p1.start()
- p2 = Process(target=vm0)
- p2.start()
- p1.join(10)
- return (queue1.get())
- else:
- self.logger.error("Thread didnt run")
-
- """##################################################################"""
- """ ######################## Stats Functions ################# #####"""
-
- def portChainDeviceMap(self):
- """Check the PC Device Stats in the ONOS."""
- response = requests.get('http://' + self.onos_hostname +
- ':8181/onos/vtn/portChainDeviceMap/' +
- self.PC_id, auth=("karaf", "karaf"))
- if (response.status_code == OK):
- self.logger.info("PortChainDeviceMap is successfully Queries")
- return(response.status_code)
- else:
- return(response.status_code)
-
- def portChainSfMap(self):
- """Check the PC SF Map Stats in the ONOS."""
- response = requests.get('http://' + self.onos_hostname +
- ':8181/onos/vtn/portChainSfMap/' +
- self.PC_id, auth=("karaf", "karaf"))
- if (response.status_code == OK):
- self.logger.info("portChainSfMap is successfully Queries")
- return(response.status_code)
- else:
- return(response.status_code)
-
- """###################################################################"""
-
- def deletePortChain(self):
- """Deletion of PortChain."""
- url = ('http://' + self.neutron_hostname + ':9696/' +
- self.osver + '/sfc/port_chains/' + self.PC_id)
- headers = {"Accept": "application/json", "Content-Type":
- "application/json", "X-Auth-Token": self.token_id}
- response = requests.delete(url, headers=headers)
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- return(response.status_code)
- else:
- return(response.status_code)
-
- def deleteFlowClassifier(self):
- """Deletion of Flow Classifier."""
- url = ("http://%s:9696/%s/sfc/"
- "flow_classifiers/%s" % (self.neutron_hostname,
- self.osver,
- self.flow_class_if))
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.delete(url, headers=headers)
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- return(response.status_code)
- else:
- return(response.status_code)
-
- def deletePortGroup(self):
- """Deletion of PortGroup."""
- for p in range(0, 1):
- url = ("http://%s:9696/%s/sfc/"
- "port_pair_groups/%s" % (self.neutron_hostname,
- self.osver,
- self.port_grp_id[p]))
- headers = {"Accept": "application/json", "X-Auth-Token":
- self.token_id}
- response = requests.delete(url, headers=headers)
- if (response.status_code == NO_CONTENT):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- else:
- return(response.status_code)
- return(response.status_code)
-
- def deletePortPair(self):
- """Deletion of Portpair."""
- for p in range(1, 2):
- url = ("http://%s:9696/%s/sfc/"
- "port_pairs/%s" % (self.neutron_hostname,
- self.osver,
- self.port_pair_id[0]))
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.delete(url, headers=headers)
- if (response.status_code == NO_CONTENT):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- else:
- return(response.status_code)
- return(response.status_code)
-
- def cleanup(self):
- """Cleanup."""
- self.logger.info("Deleting VMs")
- for y in range(0, 3):
- url = ("http://%s:8774/v2.1/"
- "/servers/%s" % (self.nova_hostname,
- self.vm[y]))
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.delete(url, headers=headers)
- if (response.status_code == NO_CONTENT):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- self.logger.debug("VM" + str(y) + " is Deleted : ")
- time.sleep(10)
- else:
- return(response.status_code)
- self.logger.info("Deleting Ports")
- for x in range(self.i, self.numTerms):
- url = ('http://' + self.neutron_hostname + ':9696/' +
- self.osver + '/ports/' + self.port_num[x])
- headers = {"Accept": "application/json", "X-Auth-Token":
- self.token_id}
- response = requests.delete(url, headers=headers)
-
- if (response.status_code == NO_CONTENT):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- self.logger.debug("Port" + str(x) + " Deleted")
- else:
- return(response.status_code)
- self.logger.info("Deleting Router")
-
- Dicdata = {}
- Dicdata['external_gateway_info'] = {}
- Dicdata = {'router': Dicdata}
- data = json.dumps(Dicdata, indent=4)
- url = ("http://%s:9696/%s/"
- "/routers/%s" % (self.neutron_hostname,
- self.osver,
- self.router_id))
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.put(url, headers=headers, data=data)
- if (response.status_code == OK):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- Dicdata1 = {}
- if self.subnetId != '':
- Dicdata1['subnet_id'] = self.subnetId
- data = json.dumps(Dicdata1, indent=4)
- url = ("http://%s:9696/%s/routers/%s"
- "/remove_router_interface.json" % (self.neutron_hostname,
- self.osver,
- self.router_id))
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.put(url, headers=headers, data=data)
- if (response.status_code == OK):
- url = ("http://%s:9696/%s/"
- "routers/%s" % (self.neutron_hostname,
- self.osver,
- self.router_id))
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.delete(url, headers=headers)
- if (response.status_code == NO_CONTENT):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- else:
- return(response.status_code)
- else:
- return(response.status_code)
- else:
- return(response.status_code)
-
- self.logger.info("Deleting Network")
- url = "http://%s:9696/%s/networks/%s" % (self.neutron_hostname,
- self.osver,
- self.net_id)
-
- headers = {"Accept": "application/json",
- "X-Auth-Token": self.token_id}
- response = requests.delete(url, headers=headers)
- if (response.status_code == NO_CONTENT):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- else:
- return(response.status_code)
-
- self.logger.info("Deleting Floating ip")
- for ip_num in range(0, 2):
- url = ("http://%s:9696/%s/floatingips"
- "/%s" % (self.neutron_hostname,
- self.osver,
- self.vm_public_id[ip_num]))
-
- headers = {"Accept": "application/json", "X-Auth-Token":
- self.token_id}
- response = requests.delete(url, headers=headers)
- if (response.status_code == NO_CONTENT):
- self.logger.debug(response.status_code)
- self.logger.debug(response.content)
- else:
- return(response.status_code)
- return(response.status_code)
diff --git a/functest/opnfv_tests/sdn/onos/teston/Readme.txt b/functest/opnfv_tests/sdn/onos/teston/Readme.txt
deleted file mode 100644
index 7393f59a..00000000
--- a/functest/opnfv_tests/sdn/onos/teston/Readme.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-1.This is a basic test run about onos,we will make them better and better
-2.This test include two suites:
-(1)Test northbound(network/subnet/ports create/update/delete)
-(2)Ovsdb test,default configuration,openflow connection,vm go onlines.
-3.Later we will make a framework to do this test \ No newline at end of file
diff --git a/functest/opnfv_tests/sdn/onos/teston/adapters/client.py b/functest/opnfv_tests/sdn/onos/teston/adapters/client.py
deleted file mode 100644
index a88d2f06..00000000
--- a/functest/opnfv_tests/sdn/onos/teston/adapters/client.py
+++ /dev/null
@@ -1,92 +0,0 @@
-"""
-Description:
- This file is used to run testcase
- 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 json
-import logging
-import pexpect
-import requests
-import time
-
-from environment import Environment
-
-
-class Client(Environment):
-
- logger = logging.getLogger(__name__)
-
- def __init__(self):
- Environment.__init__(self)
- self.loginfo = Environment()
- self.testcase = ''
-
- def RunScript(self, handle, testname, timeout=300):
- """
- Run ONOS Test Script
- Parameters:
- testname: ONOS Testcase Name
- masterusername: The server username of running ONOS
- masterpassword: The server password of running ONOS
- """
- self.testcase = testname
- self.ChangeTestCasePara(testname, self.masterusername,
- self.masterpassword)
- runhandle = handle
- runtest = (self.home + "/OnosSystemTest/TestON/bin/cli.py run " +
- testname)
- runhandle.sendline(runtest)
- circletime = 0
- lastshowscreeninfo = ''
- while True:
- Result = runhandle.expect(["PEXPECT]#", pexpect.EOF,
- pexpect.TIMEOUT])
- curshowscreeninfo = runhandle.before
- if(len(lastshowscreeninfo) != len(curshowscreeninfo)):
- self.loginfo.log(str(curshowscreeninfo)
- [len(lastshowscreeninfo)::])
- lastshowscreeninfo = curshowscreeninfo
- if Result == 0:
- self.logger.info("Done!")
- return
- time.sleep(1)
- circletime += 1
- if circletime > timeout:
- break
- self.loginfo.log("Timeout when running the test, please check!")
-
- def onosstart(self):
- # This is the compass run machine user&pass,you need to modify
-
- self.logger.info("Test Begin.....")
- self.OnosConnectionSet()
- masterhandle = self.SSHlogin(self.localhost, self.masterusername,
- self.masterpassword)
- self.OnosEnvSetup(masterhandle)
- return masterhandle
-
- def onosclean(self, handle):
- self.SSHRelease(handle)
- self.loginfo.log('Release onos handle Successful')
-
- def push_results_to_db(self, payload, pushornot=1):
- if pushornot != 1:
- return 1
- url = self.Result_DB + "/results"
- params = {"project_name": "functest", "case_name": "ONOS-" +
- self.testcase, "pod_name": 'huawei-build-2',
- "details": payload}
-
- headers = {'Content-Type': 'application/json'}
- try:
- r = requests.post(url, data=json.dumps(params), headers=headers)
- self.loginfo.log(r)
- except:
- self.loginfo.log('Error pushing results into Database')
diff --git a/functest/opnfv_tests/sdn/onos/teston/adapters/connection.py b/functest/opnfv_tests/sdn/onos/teston/adapters/connection.py
deleted file mode 100644
index a6d192ee..00000000
--- a/functest/opnfv_tests/sdn/onos/teston/adapters/connection.py
+++ /dev/null
@@ -1,200 +0,0 @@
-"""
-Description:
- This file is used to make connections
- Include ssh & exchange public-key to each other so that
- it can run without password
-
- 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 logging
-import os
-import pexpect
-import re
-
-from foundation import Foundation
-
-
-class Connection(Foundation):
-
- logger = logging.getLogger(__name__)
-
- def __init__(self):
- Foundation.__init__(self)
- self.loginfo = Foundation()
-
- def AddKnownHost(self, handle, ipaddr, username, password):
- """
- Add an user to known host,so that onos can login in with onos $ipaddr.
- parameters:
- ipaddr: ip address
- username: login user name
- password: login password
- """
- self.logger.info("Now Adding an user to known hosts " + ipaddr)
- login = handle
- login.sendline("ssh -l %s -p 8101 %s" % (username, ipaddr))
- index = 0
- while index != 2:
- index = login.expect(['assword:', 'yes/no', pexpect.EOF,
- pexpect.TIMEOUT])
- if index == 0:
- login.sendline(password)
- login.sendline("logout")
- index = login.expect(["closed", pexpect.EOF])
- if index == 0:
- self.loginfo.log("Add SSH Known Host Success!")
- break
- else:
- self.loginfo.log("Add SSH Known Host Failed! "
- "Please Check!")
- break
- login.prompt()
-
- if index == 1:
- login.sendline('yes')
-
- def GetEnvValue(self, handle, envname):
- """
- os.getenv only returns current user value
- GetEnvValue returns a environment value of
- current handle
- eg: GetEnvValue(handle,'HOME')
- """
- envhandle = handle
- envhandle.sendline('echo $' + envname)
- envhandle.prompt()
- reg = envname + '\r\n(.*)\r'
- envaluereg = re.compile(reg)
- envalue = envaluereg.search(envhandle.before)
- if envalue:
- return envalue.groups()[0]
- else:
- return None
-
- def Gensshkey(self, handle):
- """
- Generate ssh keys, used for some server have no sshkey.
- """
- self.logger.info("Now Generating SSH keys...")
- # Here file name may be id_rsa or id_ecdsa or others
- # So here will have a judgement
- keysub = handle
- filepath = self.GetEnvValue(keysub, 'HOME') + '/.ssh'
- filelist = os.listdir(filepath)
- for item in filelist:
- if 'id' in item:
- self.loginfo.log("SSH keys are exsit in ssh directory.")
- return True
- keysub.sendline("ssh-keygen -t rsa")
- Result = 0
- while Result != 2:
- Result = keysub.expect(["Overwrite", "Enter", pexpect.EOF,
- 'PEXPECT]#', pexpect.TIMEOUT])
- if Result == 0:
- keysub.sendline("y")
- if Result == 1 or Result == 2:
- keysub.sendline("\n")
- if Result == 3:
- self.loginfo.log("Generate SSH key success.")
- keysub.prompt()
- break
- if Result == 4:
- self.loginfo.log("Generate SSH key failed.")
- keysub.prompt()
- break
-
- def GetRootAuth(self, password):
- """
- Get root user
- parameters:
- password: root login password
- """
- self.logger.info("Now changing to user root")
- login = pexpect.spawn("su - root")
- index = 0
- while index != 2:
- index = login.expect(['assword:', "failure",
- pexpect.EOF, pexpect.TIMEOUT])
- if index == 0:
- login.sendline(password)
- if index == 1:
- self.loginfo.log("Change user to root failed.")
-
- login.interact()
-
- def ReleaseRootAuth(self):
- """
- Exit root user.
- """
- self.logger.info("Now Release user root")
- login = pexpect.spawn("exit")
- index = login.expect(['logout', pexpect.EOF, pexpect.TIMEOUT])
- if index == 0:
- self.loginfo.log("Release root user success.")
- if index == 1:
- self.loginfo.log("Release root user failed.")
-
- login.interact()
-
- def AddEnvIntoBashrc(self, envalue):
- """
- Add Env var into /etc/profile.
- parameters:
- envalue: environment value to add
- """
- self.logger.info("Now Adding bash environment")
- fileopen = open("/etc/profile", 'r')
- findContext = 1
- while findContext:
- findContext = fileopen.readline()
- result = findContext.find(envalue)
- if result != -1:
- break
- fileopen.close
- if result == -1:
- envAdd = open("/etc/profile", 'a+')
- envAdd.writelines("\n" + envalue)
- envAdd.close()
- self.loginfo.log("Add env to bashrc success!")
-
- def OnosRootPathChange(self, onospath):
- """
- Change ONOS root path in file:bash_profile
- onospath: path of onos root
- """
- self.logger.info("Now Changing ONOS Root Path")
- filepath = onospath + 'onos/tools/dev/bash_profile'
- line = open(filepath, 'r').readlines()
- lenall = len(line) - 1
- for i in range(lenall):
- if "export ONOS_ROOT" in line[i]:
- line[i] = 'export ONOS_ROOT=' + onospath + 'onos\n'
- NewFile = open(filepath, 'w')
- NewFile.writelines(line)
- NewFile.close
- self.logger.info("Done!")
-
- def OnosConnectionSet(self):
- """
- Intergrate for ONOS connection setup
- """
- if self.masterusername == 'root':
- filepath = '/root/'
- else:
- filepath = '/home/' + self.masterusername + '/'
- filepath = os.path.join(filepath, "onos/tools/dev/bash_profile")
- self.AddEnvIntoBashrc("source " + filepath + "\n")
- self.AddEnvIntoBashrc("export OCT=" + self.OCT)
- self.AddEnvIntoBashrc("export OC1=" + self.OC1)
- self.AddEnvIntoBashrc("export OC2=" + self.OC2)
- self.AddEnvIntoBashrc("export OC3=" + self.OC3)
- self.AddEnvIntoBashrc("export OCN=" + self.OCN)
- self.AddEnvIntoBashrc("export OCN2=" + self.OCN2)
- self.AddEnvIntoBashrc("export localhost=" + self.localhost)
diff --git a/functest/opnfv_tests/sdn/onos/teston/adapters/environment.py b/functest/opnfv_tests/sdn/onos/teston/adapters/environment.py
deleted file mode 100644
index 875a2dc9..00000000
--- a/functest/opnfv_tests/sdn/onos/teston/adapters/environment.py
+++ /dev/null
@@ -1,286 +0,0 @@
-"""
-Description:
-This file is used to setup the running environment
-Include Download code,setup environment variable
-Set onos running config
-Set user name/password
-Onos-push-keys and so on
-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 logging
-import pexpect
-from pexpect import pxssh
-import re
-import os
-import sys
-import time
-
-from connection import Connection
-
-
-class Environment(Connection):
-
- logger = logging.getLogger(__name__)
-
- def __init__(self):
- Connection.__init__(self)
- self.loginfo = Connection()
- self.masterhandle = ''
- self.home = ''
-
- def DownLoadCode(self, handle, codeurl):
- """
- Download Code use 'git clone'
- parameters:
- handle: current working handle
- codeurl: clone code url
- """
- self.logger.info("Now loading test codes! Please wait in patient...")
- originalfolder = sys.path[0]
- self.logger.info(originalfolder)
- gitclone = handle
- gitclone.sendline("git clone " + codeurl)
- index = 0
- # increment = 0
- while index != 1 or index != 4:
- index = gitclone.expect(['already exists',
- 'esolving deltas: 100%',
- 'eceiving objects',
- 'Already up-to-date',
- 'npacking objects: 100%', pexpect.EOF])
-
- filefolder = self.home + '/' + codeurl.split('/')[-1].split('.')[0]
- if index == 0:
- os.chdir(filefolder)
- os.system('git pull')
- os.chdir(originalfolder)
- self.loginfo.log('Download code success!')
- break
- elif index == 1 or index == 4:
- self.loginfo.log('Download code success!')
- gitclone.sendline("mkdir onos")
- gitclone.prompt()
- gitclone.sendline("cp -rf " + filefolder + "/tools onos/")
- gitclone.prompt()
- break
- elif index == 2:
- os.write(1, gitclone.before)
- sys.stdout.flush()
- else:
- self.loginfo.log('Download code failed!')
- self.loginfo.log('Information before' + gitclone.before)
- break
- gitclone.prompt()
-
- def InstallDefaultSoftware(self, handle):
- """
- Install default software
- parameters:
- handle(input): current working handle
- """
- self.logger.info("Now Cleaning test environment")
- handle.sendline("sudo apt-get install -y mininet")
- handle.prompt()
- handle.sendline("sudo pip install configobj")
- handle.prompt()
- handle.sendline("sudo apt-get install -y sshpass")
- handle.prompt()
- handle.sendline("OnosSystemTest/TestON/bin/cleanup.sh")
- handle.prompt()
- time.sleep(5)
- self.loginfo.log('Clean environment success!')
-
- def OnosPushKeys(self, handle, cmd, password):
- """
- Using onos-push-keys to make ssh device without password
- parameters:
- handle(input): working handle
- cmd(input): onos-push-keys xxx(xxx is device)
- password(input): login in password
- """
- self.logger.info("Now Pushing Onos Keys:" + cmd)
- Pushkeys = handle
- Pushkeys.sendline(cmd)
- Result = 0
- while Result != 2:
- Result = Pushkeys.expect(["(yes/no)", "assword:", "PEXPECT]#",
- pexpect.EOF, pexpect.TIMEOUT])
- if(Result == 0):
- Pushkeys.sendline("yes")
- if(Result == 1):
- Pushkeys.sendline(password)
- if(Result == 2):
- self.loginfo.log("ONOS Push keys Success!")
- break
- if(Result == 3):
- self.loginfo.log("ONOS Push keys Error!")
- break
- time.sleep(2)
- Pushkeys.prompt()
- self.logger.info("Done!")
-
- def SetOnosEnvVar(self, handle, masterpass, agentpass):
- """
- Setup onos pushkeys to all devices(3+2)
- parameters:
- handle(input): current working handle
- masterpass: scripts running server's password
- agentpass: onos cluster&compute node password
- """
- self.logger.info("Now Setting test environment")
- for host in self.hosts:
- self.logger.info("try to connect " + str(host))
- result = self.CheckSshNoPasswd(host)
- if not result:
- self.logger.info(
- "ssh login failed,try to copy master publickey" +
- "to agent " + str(host))
- self.CopyPublicKey(host)
- self.OnosPushKeys(handle, "onos-push-keys " + self.OCT, masterpass)
- self.OnosPushKeys(handle, "onos-push-keys " + self.OC1, agentpass)
- self.OnosPushKeys(handle, "onos-push-keys " + self.OC2, agentpass)
- self.OnosPushKeys(handle, "onos-push-keys " + self.OC3, agentpass)
- self.OnosPushKeys(handle, "onos-push-keys " + self.OCN, agentpass)
- self.OnosPushKeys(handle, "onos-push-keys " + self.OCN2, agentpass)
-
- def CheckSshNoPasswd(self, host):
- """
- Check master can connect agent with no password
- """
- login = pexpect.spawn("ssh " + str(host))
- index = 4
- while index == 4:
- index = login.expect(['(yes/no)', '>|#|\$',
- pexpect.EOF, pexpect.TIMEOUT])
- if index == 0:
- login.sendline("yes")
- index = 4
- if index == 1:
- self.loginfo.log("ssh connect to " + str(host) +
- " success,no need to copy ssh public key")
- return True
- login.interact()
- return False
-
- def ChangeOnosName(self, user, password):
- """
- Change onos name in envDefault file
- Because some command depend on this
- parameters:
- user: onos&compute node user
- password: onos&compute node password
- """
- self.logger.info("Now Changing ONOS name&password")
- filepath = self.home + '/onos/tools/build/envDefaults'
- line = open(filepath, 'r').readlines()
- lenall = len(line) - 1
- for i in range(lenall):
- if "ONOS_USER=" in line[i]:
- line[i] = line[i].replace("sdn", user)
- if "ONOS_GROUP" in line[i]:
- line[i] = line[i].replace("sdn", user)
- if "ONOS_PWD" in line[i]:
- line[i] = line[i].replace("rocks", password)
- NewFile = open(filepath, 'w')
- NewFile.writelines(line)
- NewFile.close
- self.logger.info("Done!")
-
- def ChangeTestCasePara(self, testcase, user, password):
- """
- When running test script, there\'s something need
- to change in every test folder\'s \*.param & \*.topo files
- user: onos\&compute node user
- password: onos\&compute node password
- """
- self.logger.info("Now Changing " + testcase + " name&password")
- if self.masterusername == 'root':
- filepath = '/root/'
- else:
- filepath = '/home/' + self.masterusername + '/'
- filepath = (filepath + "OnosSystemTest/TestON/tests/" +
- testcase + "/" + testcase + ".topo")
- line = open(filepath, 'r').readlines()
- lenall = len(line) - 1
- for i in range(lenall - 2):
- if("localhost" in line[i]) or ("OCT" in line[i]):
- line[i + 1] = re.sub(">\w+", ">" + user, line[i + 1])
- line[i + 2] = re.sub(">\w+", ">" + password, line[i + 2])
- if ("OC1" in line[i] or "OC2" in line[i] or "OC3" in line[i] or
- "OCN" in line[i] or "OCN2" in line[i]):
- line[i + 1] = re.sub(">\w+", ">root", line[i + 1])
- line[i + 2] = re.sub(">\w+", ">root", line[i + 2])
- NewFile = open(filepath, 'w')
- NewFile.writelines(line)
- NewFile.close
-
- def SSHlogin(self, ipaddr, username, password):
- """
- SSH login provide a connection to destination.
- parameters:
- ipaddr: ip address
- username: login user name
- password: login password
- return: handle
- """
- login = pxssh.pxssh()
- login.login(ipaddr, username, password, original_prompt='[$#>]')
- # send command ls -l
- login.sendline('ls -l')
- # match prompt
- login.prompt()
- self.logger.info("SSH login " + ipaddr + " success!")
- return login
-
- def SSHRelease(self, handle):
- # Release ssh
- handle.logout()
-
- def CopyOnostoTestbin(self):
- sourcefile = self.cipath + '/dependencies/onos'
- destifile = self.home + '/onos/tools/test/bin/'
- os.system('pwd')
- runcommand = 'cp ' + sourcefile + ' ' + destifile
- os.system(runcommand)
-
- def CopyPublicKey(self, host):
- output = os.popen('cat /root/.ssh/id_rsa.pub')
- publickey = output.read().strip('\n')
- tmphandle = self.SSHlogin(self.installer_master,
- self.installer_master_username,
- self.installer_master_password)
- tmphandle.sendline("ssh " + host + " -T \'echo " +
- str(publickey) + ">>/root/.ssh/authorized_keys\'")
- tmphandle.prompt()
- self.SSHRelease(tmphandle)
- self.logger.info("Add OCT PublicKey to " + host + " success")
-
- def OnosEnvSetup(self, handle):
- """
- Onos Environment Setup function
- """
- self.Gensshkey(handle)
- self.home = self.GetEnvValue(handle, 'HOME')
- self.AddKnownHost(handle, self.OC1, "karaf", "karaf")
- self.AddKnownHost(handle, self.OC2, "karaf", "karaf")
- self.AddKnownHost(handle, self.OC3, "karaf", "karaf")
- self.DownLoadCode(handle,
- 'https://github.com/wuwenbin2/OnosSystemTest.git')
- # self.DownLoadCode(handle, 'https://gerrit.onosproject.org/onos')
- if self.masterusername == 'root':
- filepath = '/root/'
- else:
- filepath = '/home/' + self.masterusername + '/'
- self.OnosRootPathChange(filepath)
- self.CopyOnostoTestbin()
- self.ChangeOnosName(self.agentusername, self.agentpassword)
- self.InstallDefaultSoftware(handle)
- self.SetOnosEnvVar(handle, self.masterpassword, self.agentpassword)
diff --git a/functest/opnfv_tests/sdn/onos/teston/adapters/foundation.py b/functest/opnfv_tests/sdn/onos/teston/adapters/foundation.py
deleted file mode 100644
index aed98ee4..00000000
--- a/functest/opnfv_tests/sdn/onos/teston/adapters/foundation.py
+++ /dev/null
@@ -1,95 +0,0 @@
-"""
-Description:
- This file include basis functions
- 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 logging
-import os
-import re
-import time
-
-from functest.utils.constants import CONST
-
-
-class Foundation(object):
-
- def __init__(self):
-
- # currentpath = os.getcwd()
- currentpath = ('{0}/sdn/onos/teston/ci'
- .format(CONST.__getattribute__('dir_functest_data')))
- self.cipath = currentpath
- self.logdir = os.path.join(currentpath, 'log')
- self.workhome = currentpath[0: currentpath.rfind('opnfv_tests') - 1]
- self.Result_DB = ''
- filename = time.strftime('%Y-%m-%d-%H-%M-%S') + '.log'
- self.logfilepath = os.path.join(self.logdir, filename)
- self.starttime = datetime.datetime.now()
-
- def log(self, loginfo):
- """
- Record log in log directory for deploying test environment
- parameters:
- loginfo(input): record info
- """
- logging.basicConfig(level=logging.INFO,
- format='%(asctime)s %(filename)s:%(message)s',
- datefmt='%d %b %Y %H:%M:%S',
- filename=self.logfilepath,
- filemode='w')
- filelog = logging.FileHandler(self.logfilepath)
- logging.getLogger('Functest').addHandler(filelog)
- logging.info(loginfo)
-
- def getdefaultpara(self):
- """
- Get Default Parameters value
- """
- self.Result_DB = CONST.__getattribute__("results_test_db_url")
- self.masterusername = CONST.__getattribute__('ONOS_onosbench_username')
- self.masterpassword = CONST.__getattribute__('ONOS_onosbench_password')
- self.agentusername = CONST.__getattribute__('ONOS_onoscli_username')
- self.agentpassword = CONST.__getattribute__('ONOS_onoscli_password')
- self.runtimeout = CONST.__getattribute__('ONOS_runtimeout')
- self.OCT = CONST.__getattribute__('ONOS_environment_OCT')
- self.OC1 = CONST.__getattribute__('ONOS_environment_OC1')
- self.OC2 = CONST.__getattribute__('ONOS_environment_OC2')
- self.OC3 = CONST.__getattribute__('ONOS_environment_OC3')
- self.OCN = CONST.__getattribute__('ONOS_environment_OCN')
- self.OCN2 = CONST.__getattribute__('ONOS_environment_OCN2')
- self.installer_master = CONST.__getattribute__(
- 'ONOS_environment_installer_master')
- self.installer_master_username = (
- CONST.__getattribute__(
- 'ONOS_environment_installer_master_username'))
- self.installer_master_password = (
- CONST.__getattribute__(
- 'ONOS_environment_installer_master_password'))
- self.hosts = [self.OC1, self.OCN, self.OCN2]
- self.localhost = self.OCT
-
- def GetResult(self):
- cmd = "cat " + self.logfilepath + " | grep Fail"
- Resultbuffer = os.popen(cmd).read()
- duration = datetime.datetime.now() - self.starttime
- time.sleep(2)
-
- if re.search("[1-9]+", Resultbuffer):
- self.log("Testcase Fails\n" + Resultbuffer)
- Result = "POK"
- else:
- self.log("Testcases Pass")
- Result = "OK"
- payload = {'timestart': str(self.starttime),
- 'duration': str(duration), 'status': Result}
-
- return payload
diff --git a/functest/opnfv_tests/sdn/onos/teston/dependencies/onos b/functest/opnfv_tests/sdn/onos/teston/dependencies/onos
deleted file mode 100644
index bb02fa89..00000000
--- a/functest/opnfv_tests/sdn/onos/teston/dependencies/onos
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-# -----------------------------------------------------------------------------
-# ONOS remote command-line client.
-# -----------------------------------------------------------------------------
-#
-# 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
-#
-
-[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
-. /root/.bashrc
-. $ONOS_ROOT/tools/build/envDefaults
-. $ONOS_ROOT/tools/test/bin/find-node.sh
-
-[ "$1" = "-w" ] && shift && onos-wait-for-start $1
-
-[ -n "$1" ] && OCI=$(find_node $1) && shift
-
-if which client 1>/dev/null 2>&1 && [ -z "$ONOS_USE_SSH" ]; then
- # Use Karaf client only if we can and are allowed to
- unset KARAF_HOME
- client -h $OCI -u karaf "$@" 2>/dev/null
-else
- # Otherwise use raw ssh; strict checking is off for dev environments only
- #ssh -p 8101 -o StrictHostKeyChecking=no $OCI "$@"
- sshpass -p karaf ssh -l karaf -p 8101 $OCI "$@"
-fi
diff --git a/functest/opnfv_tests/sdn/onos/teston/log/gitignore b/functest/opnfv_tests/sdn/onos/teston/log/gitignore
deleted file mode 100644
index e69de29b..00000000
--- a/functest/opnfv_tests/sdn/onos/teston/log/gitignore
+++ /dev/null
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
index b07eaee2..8ed7f0dd 100644
--- a/functest/opnfv_tests/vnf/ims/cloudify_ims.py
+++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
@@ -281,6 +281,7 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
external_network_name=ext_net_name,
network_name=network_settings.name
))
+ self.result = 1/3 * 100
return True
def deploy_vnf(self):
@@ -330,6 +331,7 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
self.__logger.info(execution)
if execution.status == 'terminated':
self.details['vnf'].update(status='PASS', duration=duration)
+ self.result += 1/3 * 100
result = True
else:
self.details['vnf'].update(status='FAIL', duration=duration)
@@ -355,12 +357,20 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase):
dns_ip=dns_ip,
public_domain=self.vnf['inputs']["public_domain"])
duration = time.time() - start_time
- short_result = sig_test_format(vims_test_result)
+ short_result, nb_test = sig_test_format(vims_test_result)
self.__logger.info(short_result)
- self.details['test_vnf'].update(status='PASS',
- result=short_result,
+ self.details['test_vnf'].update(result=short_result,
full_result=vims_test_result,
duration=duration)
+ try:
+ vnf_test_rate = short_result['passed'] / nb_test
+ # orchestrator + vnf + test_vnf
+ self.result += vnf_test_rate / 3 * 100
+ except ZeroDivisionError:
+ self.__logger.error("No test has been executed")
+ self.details['test_vnf'].update(status='FAIL')
+ return False
+
return True
def clean(self):
@@ -507,11 +517,12 @@ def sig_test_format(sig_test):
nb_failures += 1
elif data_test['result'] == "Skipped":
nb_skipped += 1
- total_sig_test_result = {}
- total_sig_test_result['passed'] = nb_passed
- total_sig_test_result['failures'] = nb_failures
- total_sig_test_result['skipped'] = nb_skipped
- return total_sig_test_result
+ short_sig_test_result = {}
+ short_sig_test_result['passed'] = nb_passed
+ short_sig_test_result['failures'] = nb_failures
+ short_sig_test_result['skipped'] = nb_skipped
+ nb_test = nb_passed + nb_skipped
+ return (short_sig_test_result, nb_test)
def run_blocking_ssh_command(ssh, cmd, error_msg="Unable to run this command"):
diff --git a/functest/opnfv_tests/vnf/ims/orchestra_clearwaterims.py b/functest/opnfv_tests/vnf/ims/orchestra_clearwaterims.py
index a5405996..5154dea2 100644
--- a/functest/opnfv_tests/vnf/ims/orchestra_clearwaterims.py
+++ b/functest/opnfv_tests/vnf/ims/orchestra_clearwaterims.py
@@ -234,7 +234,8 @@ class ClearwaterImsVnf(vnf.VnfOnBoarding):
ImageSettings(name=image_name,
image_user='cloud',
img_format='qcow2',
- image_file=image_file))
+ image_file=image_file,
+ public=True))
image.create()
# self.created_resources.append(image);
diff --git a/functest/opnfv_tests/vnf/ims/orchestra_openims.py b/functest/opnfv_tests/vnf/ims/orchestra_openims.py
index f8acada4..45440704 100644
--- a/functest/opnfv_tests/vnf/ims/orchestra_openims.py
+++ b/functest/opnfv_tests/vnf/ims/orchestra_openims.py
@@ -231,7 +231,8 @@ class OpenImsVnf(vnf.VnfOnBoarding):
ImageSettings(name=image_name,
image_user='cloud',
img_format='qcow2',
- image_file=image_file))
+ image_file=image_file,
+ public=True))
image.create()
# self.created_resources.append(image);
diff --git a/functest/opnfv_tests/vnf/router/cloudify_vrouter.py b/functest/opnfv_tests/vnf/router/cloudify_vrouter.py
new file mode 100644
index 00000000..c3cccb98
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/cloudify_vrouter.py
@@ -0,0 +1,542 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Okinawa Open Laboratory 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
+
+"""vrouter testcase implementation."""
+
+import logging
+import os
+import time
+
+from cloudify_rest_client import CloudifyClient
+from cloudify_rest_client.executions import Execution
+from scp import SCPClient
+import yaml
+
+from functest.opnfv_tests.openstack.snaps import snaps_utils
+import functest.opnfv_tests.vnf.router.vrouter_base as vrouter_base
+from functest.utils.constants import CONST
+import functest.utils.openstack_utils as os_utils
+
+from git import Repo
+
+from snaps.openstack.os_credentials import OSCreds
+from snaps.openstack.create_network import (NetworkSettings, SubnetSettings,
+ OpenStackNetwork)
+from snaps.openstack.create_security_group import (SecurityGroupSettings,
+ SecurityGroupRuleSettings,
+ Direction, Protocol,
+ OpenStackSecurityGroup)
+from snaps.openstack.create_router import RouterSettings, OpenStackRouter
+from snaps.openstack.create_instance import (VmInstanceSettings,
+ FloatingIpSettings,
+ OpenStackVmInstance)
+from snaps.openstack.create_flavor import FlavorSettings, OpenStackFlavor
+from snaps.openstack.create_image import ImageSettings, OpenStackImage
+from snaps.openstack.create_keypairs import KeypairSettings, OpenStackKeypair
+from snaps.openstack.create_network import PortSettings
+import snaps.openstack.utils.glance_utils as glance_utils
+
+from functest.opnfv_tests.vnf.router.utilvnf import Utilvnf
+
+__author__ = "Shuya Nakama <shuya.nakama@okinawaopenlabs.org>"
+
+
+class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase):
+ """vrouter testcase deployed with Cloudify Orchestrator."""
+
+ __logger = logging.getLogger(__name__)
+ name = __name__
+
+ def __init__(self, **kwargs):
+ if "case_name" not in kwargs:
+ kwargs["case_name"] = "vyos_vrouter"
+ super(CloudifyVrouter, self).__init__(**kwargs)
+
+ # Retrieve the configuration
+ try:
+ self.config = CONST.__getattribute__(
+ 'vnf_{}_config'.format(self.case_name))
+ except Exception:
+ raise Exception("VNF config file not found")
+
+ self.snaps_creds = ''
+ self.created_object = []
+
+ self.cfy_manager_ip = ''
+ self.util_info = {}
+ self.deployment_name = ''
+
+ config_file = os.path.join(self.case_dir, self.config)
+ self.orchestrator = dict(
+ requirements=get_config("orchestrator.requirements", config_file),
+ )
+ self.details['orchestrator'] = dict(
+ name=get_config("orchestrator.name", config_file),
+ version=get_config("orchestrator.version", config_file),
+ status='ERROR',
+ result=''
+ )
+ self.__logger.debug("Orchestrator configuration %s", self.orchestrator)
+ self.__logger.debug("name = %s", self.name)
+ self.vnf = dict(
+ descriptor=get_config("vnf.descriptor", config_file),
+ inputs=get_config("vnf.inputs", config_file),
+ requirements=get_config("vnf.requirements", config_file)
+ )
+ self.details['vnf'] = dict(
+ descriptor_version=self.vnf['descriptor']['version'],
+ name=get_config("vnf.name", config_file),
+ version=get_config("vnf.version", config_file),
+ )
+ self.__logger.debug("VNF configuration: %s", self.vnf)
+
+ self.util = Utilvnf()
+
+ self.details['test_vnf'] = dict(
+ name=get_config("vnf_test_suite.name", config_file),
+ version=get_config("vnf_test_suite.version", config_file)
+ )
+ self.images = get_config("tenant_images", config_file)
+ self.__logger.info("Images needed for vrouter: %s", self.images)
+
+ def prepare(self):
+ super(CloudifyVrouter, self).prepare()
+
+ self.__logger.info("Additional pre-configuration steps")
+
+ self.snaps_creds = OSCreds(
+ username=self.creds['username'],
+ password=self.creds['password'],
+ auth_url=self.creds['auth_url'],
+ project_name=self.creds['tenant'],
+ identity_api_version=int(os_utils.get_keystone_client_version()))
+
+ self.util.set_credentials(self.creds["username"],
+ self.creds["password"],
+ self.creds["auth_url"],
+ self.creds["tenant"])
+
+ # needs some images
+ self.__logger.info("Upload some OS images if it doesn't exist")
+ for image_name, image_file in self.images.iteritems():
+ self.__logger.info("image: %s, file: %s", image_name, image_file)
+ if image_file and image_name:
+ image_creator = OpenStackImage(
+ self.snaps_creds,
+ ImageSettings(name=image_name,
+ image_user='cloud',
+ img_format='qcow2',
+ image_file=image_file))
+ image_creator.create()
+ self.created_object.append(image_creator)
+
+ def deploy_orchestrator(self):
+ """
+ Deploy Cloudify Manager.
+ network, security group, fip, VM creation
+ """
+ # network creation
+
+ start_time = time.time()
+ self.__logger.info("Creating keypair ...")
+ kp_file = os.path.join(self.data_dir, "cloudify_vrouter.pem")
+ keypair_settings = KeypairSettings(name='cloudify_vrouter_kp',
+ private_filepath=kp_file)
+ keypair_creator = OpenStackKeypair(self.snaps_creds, keypair_settings)
+ keypair_creator.create()
+ self.created_object.append(keypair_creator)
+
+ self.__logger.info("Creating full network ...")
+ subnet_settings = SubnetSettings(name='cloudify_vrouter_subnet',
+ cidr='10.67.79.0/24')
+ network_settings = NetworkSettings(name='cloudify_vrouter_network',
+ subnet_settings=[subnet_settings])
+ network_creator = OpenStackNetwork(self.snaps_creds, network_settings)
+ network_creator.create()
+ self.created_object.append(network_creator)
+ ext_net_name = snaps_utils.get_ext_net_name(self.snaps_creds)
+ router_creator = OpenStackRouter(
+ self.snaps_creds,
+ RouterSettings(
+ name='cloudify_vrouter_router',
+ external_gateway=ext_net_name,
+ internal_subnets=[subnet_settings.name]))
+ router_creator.create()
+ self.created_object.append(router_creator)
+
+ # security group creation
+ self.__logger.info("Creating security group for cloudify manager vm")
+ sg_rules = list()
+ sg_rules.append(
+ SecurityGroupRuleSettings(sec_grp_name="sg-cloudify-manager",
+ direction=Direction.ingress,
+ protocol=Protocol.tcp, port_range_min=1,
+ port_range_max=65535))
+ sg_rules.append(
+ SecurityGroupRuleSettings(sec_grp_name="sg-cloudify-manager",
+ direction=Direction.ingress,
+ protocol=Protocol.udp, port_range_min=1,
+ port_range_max=65535))
+
+ security_group_creator = OpenStackSecurityGroup(
+ self.snaps_creds,
+ SecurityGroupSettings(
+ name="sg-cloudify-manager",
+ rule_settings=sg_rules))
+
+ security_group_creator.create()
+ self.created_object.append(security_group_creator)
+
+ # orchestrator VM flavor
+ self.__logger.info("Get or create flavor for cloudify manager vm ...")
+
+ flavor_settings = FlavorSettings(
+ name=self.orchestrator['requirements']['flavor']['name'],
+ ram=self.orchestrator['requirements']['flavor']['ram_min'],
+ disk=50,
+ vcpus=2)
+ flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings)
+ flavor_creator.create()
+ self.created_object.append(flavor_creator)
+ image_settings = ImageSettings(
+ name=self.orchestrator['requirements']['os_image'],
+ image_user='centos',
+ exists=True)
+
+ port_settings = PortSettings(name='cloudify_manager_port',
+ network_name=network_settings.name)
+
+ manager_settings = VmInstanceSettings(
+ name='cloudify_manager',
+ flavor=flavor_settings.name,
+ port_settings=[port_settings],
+ security_group_names=[
+ security_group_creator.sec_grp_settings.name],
+ floating_ip_settings=[FloatingIpSettings(
+ name='cloudify_manager_fip',
+ port_name=port_settings.name,
+ router_name=router_creator.router_settings.name)])
+
+ manager_creator = OpenStackVmInstance(self.snaps_creds,
+ manager_settings,
+ image_settings,
+ keypair_settings)
+
+ self.__logger.info("Creating cloudify manager VM")
+ manager_creator.create()
+ self.created_object.append(manager_creator)
+
+ public_auth_url = os_utils.get_endpoint('identity')
+
+ self.__logger.info("Set creds for cloudify manager")
+ cfy_creds = dict(keystone_username=self.tenant_name,
+ keystone_password=self.tenant_name,
+ keystone_tenant_name=self.tenant_name,
+ keystone_url=public_auth_url)
+
+ cfy_client = CloudifyClient(host=manager_creator.get_floating_ip().ip,
+ username='admin',
+ password='admin',
+ tenant='default_tenant')
+
+ self.orchestrator['object'] = cfy_client
+
+ self.cfy_manager_ip = manager_creator.get_floating_ip().ip
+
+ self.__logger.info("Attemps running status of the Manager")
+ cfy_status = None
+ retry = 10
+ while str(cfy_status) != 'running' and retry:
+ try:
+ cfy_status = cfy_client.manager.get_status()['status']
+ self.__logger.debug("The current manager status is %s",
+ cfy_status)
+ except Exception: # pylint: disable=broad-except
+ self.__logger.warning("Cloudify Manager isn't " +
+ "up and running. Retrying ...")
+ retry = retry - 1
+ time.sleep(30)
+
+ if str(cfy_status) == 'running':
+ self.__logger.info("Cloudify Manager is up and running")
+ else:
+ raise Exception("Cloudify Manager isn't up and running")
+
+ self.__logger.info("Put OpenStack creds in manager")
+ secrets_list = cfy_client.secrets.list()
+ for k, val in cfy_creds.iteritems():
+ if not any(d.get('key', None) == k for d in secrets_list):
+ cfy_client.secrets.create(k, val)
+ else:
+ cfy_client.secrets.update(k, val)
+
+ duration = time.time() - start_time
+
+ self.__logger.info("Put private keypair in manager")
+ if manager_creator.vm_ssh_active(block=True):
+ ssh = manager_creator.ssh_client()
+ scp = SCPClient(ssh.get_transport(), socket_timeout=15.0)
+ scp.put(kp_file, '~/')
+ cmd = "sudo cp ~/cloudify_vrouter.pem /etc/cloudify/"
+ run_blocking_ssh_command(ssh, cmd)
+ cmd = "sudo chmod 444 /etc/cloudify/cloudify_vrouter.pem"
+ run_blocking_ssh_command(ssh, cmd)
+ cmd = "sudo yum install -y gcc python-devel"
+ run_blocking_ssh_command(
+ ssh, cmd, "Unable to install packages on manager")
+
+ self.details['orchestrator'].update(status='PASS', duration=duration)
+
+ self.vnf['inputs'].update(dict(external_network_name=ext_net_name))
+
+ return True
+
+ def deploy_vnf(self):
+ start_time = time.time()
+
+ self.__logger.info("Upload VNFD")
+ cfy_client = self.orchestrator['object']
+ descriptor = self.vnf['descriptor']
+ self.deployment_name = descriptor.get('name')
+
+ vrouter_blueprint_dir = os.path.join(self.data_dir,
+ self.util.blueprint_dir)
+ if not os.path.exists(vrouter_blueprint_dir):
+ Repo.clone_from(descriptor.get('url'),
+ vrouter_blueprint_dir,
+ branch=descriptor.get('version'))
+
+ cfy_client.blueprints.upload(vrouter_blueprint_dir +
+ self.util.blueprint_file_name,
+ descriptor.get('name'))
+
+ self.__logger.info("Get or create flavor for vrouter")
+ flavor_settings = FlavorSettings(
+ name=self.vnf['requirements']['flavor']['name'],
+ ram=self.vnf['requirements']['flavor']['ram_min'],
+ disk=25,
+ vcpus=1)
+ flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings)
+ flavor = flavor_creator.create()
+ self.created_object.append(flavor_creator)
+
+ # set image name
+ glance = glance_utils.glance_client(self.snaps_creds)
+ image = glance_utils.get_image(glance,
+ "vyos1.1.7")
+ self.vnf['inputs'].update(dict(target_vnf_image_id=image.id))
+ self.vnf['inputs'].update(dict(reference_vnf_image_id=image.id))
+
+ # set flavor id
+ self.vnf['inputs'].update(dict(target_vnf_flavor_id=flavor.id))
+ self.vnf['inputs'].update(dict(reference_vnf_flavor_id=flavor.id))
+
+ self.vnf['inputs'].update(dict(keystone_username=self.tenant_name))
+ self.vnf['inputs'].update(dict(keystone_password=self.tenant_name))
+ self.vnf['inputs'].update(dict(keystone_tenant_name=self.tenant_name))
+ self.vnf['inputs'].update(
+ dict(keystone_url=os_utils.get_endpoint('identity')))
+
+ self.__logger.info("Create VNF Instance")
+ cfy_client.deployments.create(descriptor.get('name'),
+ descriptor.get('name'),
+ self.vnf.get('inputs'))
+
+ wait_for_execution(cfy_client,
+ get_execution_id(
+ cfy_client, descriptor.get('name')),
+ self.__logger,
+ timeout=7200)
+
+ self.__logger.info("Start the VNF Instance deployment")
+ execution = cfy_client.executions.start(descriptor.get('name'),
+ 'install')
+ # Show execution log
+ execution = wait_for_execution(cfy_client, execution, self.__logger)
+
+ duration = time.time() - start_time
+
+ self.__logger.info(execution)
+ if execution.status == 'terminated':
+ self.details['vnf'].update(status='PASS', duration=duration)
+ result = True
+ else:
+ self.details['vnf'].update(status='FAIL', duration=duration)
+ result = False
+ return result
+
+ def test_vnf(self):
+ cfy_client = self.orchestrator['object']
+ credentials = {"username": self.creds["username"],
+ "password": self.creds["password"],
+ "auth_url": self.creds["auth_url"],
+ "tenant_name": self.creds["tenant"],
+ "region_name": os.environ['OS_REGION_NAME']}
+
+ self.util_info = {"credentials": credentials,
+ "cfy": cfy_client,
+ "vnf_data_dir": self.util.vnf_data_dir}
+
+ start_time = time.time()
+
+ result, test_result_data = super(CloudifyVrouter, self).test_vnf()
+
+ duration = time.time() - start_time
+
+ if result:
+ self.details['test_vnf'].update(status='PASS',
+ result='OK',
+ full_result=test_result_data,
+ duration=duration)
+ else:
+ self.details['test_vnf'].update(status='FAIL',
+ result='NG',
+ full_result=test_result_data,
+ duration=duration)
+
+ return True
+
+ def clean(self):
+ try:
+ cfy_client = self.orchestrator['object']
+ dep_name = self.vnf['descriptor'].get('name')
+ # kill existing execution
+ self.__logger.info('Deleting the current deployment')
+ exec_list = cfy_client.executions.list(dep_name)
+ for execution in exec_list:
+ if execution['status'] == "started":
+ try:
+ cfy_client.executions.cancel(execution['id'],
+ force=True)
+ except: # pylint: disable=broad-except
+ self.__logger.warn("Can't cancel the current exec")
+
+ execution = cfy_client.executions.start(
+ dep_name,
+ 'uninstall',
+ parameters=dict(ignore_failure=True))
+
+ wait_for_execution(cfy_client, execution, self.__logger)
+ cfy_client.deployments.delete(self.vnf['descriptor'].get('name'))
+ cfy_client.blueprints.delete(self.vnf['descriptor'].get('name'))
+ except: # pylint: disable=broad-except
+ self.__logger.warn("Some issue during the undeployment ..")
+ self.__logger.warn("Tenant clean continue ..")
+
+ self.__logger.info('Remove the cloudify manager OS object ..')
+ for creator in reversed(self.created_object):
+ try:
+ creator.clean()
+ except Exception as exc:
+ self.logger.error('Unexpected error cleaning - %s', exc)
+
+ super(CloudifyVrouter, self).clean()
+
+ def run(self, **kwargs):
+ """Execute CloudifyVrouter test case."""
+ return super(CloudifyVrouter, self).run(**kwargs)
+
+ def get_vnf_info_list(self, target_vnf_name):
+ return self.util.get_vnf_info_list(self.cfy_manager_ip,
+ self.deployment_name,
+ target_vnf_name)
+
+
+# ----------------------------------------------------------
+#
+# YAML UTILS
+#
+# -----------------------------------------------------------
+def get_config(parameter, file_path):
+ """
+ Get config parameter.
+ 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_path) as config_file:
+ file_yaml = yaml.safe_load(config_file)
+ config_file.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 wait_for_execution(client, execution, logger, timeout=7200, ):
+ """Wait for a workflow execution on Cloudify Manager."""
+ # if execution already ended - return without waiting
+ if execution.status in Execution.END_STATES:
+ return execution
+
+ if timeout is not None:
+ deadline = time.time() + timeout
+
+ # Poll for execution status and execution logs, until execution ends
+ # and we receive an event of type in WORKFLOW_END_TYPES
+ offset = 0
+ batch_size = 50
+ event_list = []
+ execution_ended = False
+ while True:
+ event_list = client.events.list(
+ execution_id=execution.id,
+ _offset=offset,
+ _size=batch_size,
+ include_logs=False,
+ sort='@timestamp').items
+
+ offset = offset + len(event_list)
+ for event in event_list:
+ logger.debug(event.get('message'))
+
+ if timeout is not None:
+ if time.time() > deadline:
+ raise RuntimeError(
+ 'execution of operation {0} for deployment {1} '
+ 'timed out'.format(execution.workflow_id,
+ execution.deployment_id))
+ else:
+ # update the remaining timeout
+ timeout = deadline - time.time()
+
+ if not execution_ended:
+ execution = client.executions.get(execution.id)
+ execution_ended = execution.status in Execution.END_STATES
+
+ if execution_ended:
+ break
+
+ time.sleep(5)
+
+ return execution
+
+
+def get_execution_id(client, deployment_id):
+ """
+ Get the execution id of a env preparation.
+ network, security group, fip, VM creation
+ """
+ executions = client.executions.list(deployment_id=deployment_id)
+ for execution in executions:
+ if execution.workflow_id == 'create_deployment_environment':
+ return execution
+ raise RuntimeError('Failed to get create_deployment_environment '
+ 'workflow execution.'
+ 'Available executions: {0}'.format(executions))
+
+
+def run_blocking_ssh_command(ssh, cmd, error_msg="Unable to run this command"):
+ """Command to run ssh command with the exit status."""
+ (_, stdout, _) = ssh.exec_command(cmd)
+ if stdout.channel.recv_exit_status() != 0:
+ raise Exception(error_msg)
diff --git a/functest/opnfv_tests/vnf/router/cloudify_vrouter.yaml b/functest/opnfv_tests/vnf/router/cloudify_vrouter.yaml
new file mode 100644
index 00000000..c09477ab
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/cloudify_vrouter.yaml
@@ -0,0 +1,31 @@
+tenant_images:
+ cloudify_manager_4.0: /home/opnfv/functest/images/cloudify-manager-premium-4.0.1.qcow2
+ vyos1.1.7: /home/opnfv/functest/images/vyos-1.1.7.img
+test_data:
+ url: 'https://github.com/oolorg/opnfv-vnf-data.git'
+ branch: 'master'
+orchestrator:
+ name: cloudify
+ version: '4.0'
+ requirements:
+ flavor:
+ name: m1.medium
+ ram_min: 4096
+ os_image: 'cloudify_manager_4.0'
+vnf:
+ name: vyos1.1.7
+ version: '1.1.7'
+ descriptor:
+ url: https://github.com/oolorg/opnfv-vnf-vyos-blueprint/
+ name: vrouter-opnfv
+ version: 'master'
+ requirements:
+ flavor:
+ name: m1.medium
+ ram_min: 2048
+ inputs:
+ external_network_name: admin_floating_net
+ region: RegionOne
+vnf_test_suite:
+ name: vyos-vrouter-test
+ version: "1.0"
diff --git a/functest/opnfv_tests/sdn/onos/__init__.py b/functest/opnfv_tests/vnf/router/test_controller/__init__.py
index e69de29b..e69de29b 100644
--- a/functest/opnfv_tests/sdn/onos/__init__.py
+++ b/functest/opnfv_tests/vnf/router/test_controller/__init__.py
diff --git a/functest/opnfv_tests/vnf/router/test_controller/function_test_exec.py b/functest/opnfv_tests/vnf/router/test_controller/function_test_exec.py
new file mode 100644
index 00000000..236447e0
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/test_controller/function_test_exec.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Okinawa Open Laboratory 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
+
+"""vrouter function test execution module"""
+
+import logging
+import time
+import yaml
+
+from functest.opnfv_tests.vnf.router.utilvnf import Utilvnf
+from functest.opnfv_tests.vnf.router.vnf_controller.vnf_controller import (
+ VnfController)
+
+
+class FunctionTestExec(object):
+ """vrouter function test execution class"""
+
+ logger = logging.getLogger(__name__)
+
+ def __init__(self, util_info):
+ self.logger.debug("init test exec")
+ self.util = Utilvnf()
+ credentials = util_info["credentials"]
+ self.vnf_ctrl = VnfController(util_info)
+
+ test_cmd_map_file = open(self.util.vnf_data_dir +
+ self.util.opnfv_vnf_data_dir +
+ self.util.command_template_dir +
+ self.util.test_cmd_map_yaml_file,
+ 'r')
+ self.test_cmd_map_yaml = yaml.safe_load(test_cmd_map_file)
+ test_cmd_map_file.close()
+
+ self.util.set_credentials(credentials["username"],
+ credentials["password"],
+ credentials["auth_url"],
+ credentials["tenant_name"],
+ credentials["region_name"])
+
+ with open(self.util.test_env_config_yaml) as file_fd:
+ test_env_config_yaml = yaml.safe_load(file_fd)
+ file_fd.close()
+
+ self.protocol_stable_wait = test_env_config_yaml.get("general").get(
+ "protocol_stable_wait")
+
+ def config_target_vnf(self, target_vnf, reference_vnf, test_kind):
+ self.logger.debug("Configuration to target vnf")
+ test_info = self.test_cmd_map_yaml[target_vnf["os_type"]]
+ test_cmd_file_path = test_info[test_kind]["pre_command_target"]
+ target_parameter_file_path = test_info[test_kind]["parameter_target"]
+ prompt_file_path = test_info["prompt"]
+
+ return self.vnf_ctrl.config_vnf(target_vnf,
+ reference_vnf,
+ test_cmd_file_path,
+ target_parameter_file_path,
+ prompt_file_path)
+
+ def config_reference_vnf(self, target_vnf, reference_vnf, test_kind):
+ self.logger.debug("Configuration to reference vnf")
+ test_info = self.test_cmd_map_yaml[reference_vnf["os_type"]]
+ test_cmd_file_path = test_info[test_kind]["pre_command_reference"]
+ reference_parameter_file_path = test_info[test_kind][
+ "parameter_reference"]
+ prompt_file_path = test_info["prompt"]
+
+ return self.vnf_ctrl.config_vnf(reference_vnf,
+ target_vnf,
+ test_cmd_file_path,
+ reference_parameter_file_path,
+ prompt_file_path)
+
+ def result_check(self, target_vnf, reference_vnf, test_kind, test_list):
+ test_info = self.test_cmd_map_yaml[target_vnf["os_type"]]
+ target_parameter_file_path = test_info[test_kind]["parameter_target"]
+ prompt_file_path = test_info["prompt"]
+ check_rule_file_path_list = []
+
+ for test in test_list:
+ check_rule_file_path_list.append(test_info[test_kind][test])
+
+ return self.vnf_ctrl.result_check(target_vnf,
+ reference_vnf,
+ check_rule_file_path_list,
+ target_parameter_file_path,
+ prompt_file_path)
+
+ def run(self, target_vnf, reference_vnf_list, test_info, test_list):
+ test_result_data = {}
+ test_kind = test_info["protocol"]
+ for reference_vnf in reference_vnf_list:
+ self.logger.debug("Start config command " +
+ target_vnf["vnf_name"] + " and " +
+ reference_vnf["vnf_name"])
+
+ result = self.config_target_vnf(target_vnf,
+ reference_vnf,
+ test_kind)
+ if not result:
+ return False, test_result_data
+
+ result = self.config_reference_vnf(target_vnf,
+ reference_vnf,
+ test_kind)
+ if not result:
+ return False, test_result_data
+
+ self.logger.debug("Finish config command.")
+
+ self.logger.debug("Waiting for protocol stable.")
+ time.sleep(self.protocol_stable_wait)
+
+ self.logger.debug("Start check method")
+
+ (result, res_dict_data_list) = self.result_check(target_vnf,
+ reference_vnf,
+ test_kind,
+ test_list)
+
+ test_result_data = {"test_kind": test_info["test_kind"],
+ "protocol": test_info["protocol"],
+ "result": res_dict_data_list}
+
+ if not result:
+ self.logger.debug("Error check method.")
+ return False, test_result_data
+
+ self.logger.debug("Finish check method.")
+
+ return True, test_result_data
diff --git a/functest/opnfv_tests/vnf/router/test_scenario.yaml b/functest/opnfv_tests/vnf/router/test_scenario.yaml
new file mode 100644
index 00000000..03185592
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/test_scenario.yaml
@@ -0,0 +1,27 @@
+test_scenario_list:
+ -
+ test_type: 'function_test'
+ vnf_list:
+ -
+ vnf_name: 'target_vnf'
+ os_type: 'vyos'
+ image_name: 'vyos1.1.7'
+ flavor_name: 'm1.medium'
+ -
+ vnf_name: 'reference_vnf'
+ os_type: 'vyos'
+ image_name: 'vyos1.1.7'
+ flavor_name: 'm1.medium'
+ function_test_list:
+ -
+ target_vnf_name: 'target_vnf'
+ test_list:
+ -
+ test_kind: 'Interoperability'
+ protocol: 'BGP'
+ BGP:
+ - 'Checking_the_peer_of_BGP'
+ - 'Checking_the_status_of_BGP'
+ - 'Checking_the_advertised_routes'
+ - 'Checking_the_received_routes'
+ - 'Checking_the_routing_table'
diff --git a/functest/opnfv_tests/vnf/router/utilvnf.py b/functest/opnfv_tests/vnf/router/utilvnf.py
new file mode 100644
index 00000000..084af331
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/utilvnf.py
@@ -0,0 +1,345 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Okinawa Open Laboratory 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
+
+""" Utility module of vrouter testcase """
+
+import json
+import logging
+import os
+import pkg_resources
+import requests
+import yaml
+
+from functest.utils.constants import CONST
+from git import Repo
+from novaclient import client as novaclient
+from keystoneauth1 import session
+from keystoneauth1 import loading
+from requests.auth import HTTPBasicAuth
+
+RESULT_SPRIT_INDEX = {
+ "transfer": 8,
+ "bandwidth": 6,
+ "jitter": 4,
+ "los_total": 2,
+ "pkt_loss": 1
+}
+
+BIT_PER_BYTE = 8
+
+NOVA_CLIENT_API_VERSION = '2'
+NOVA_CILENT_NETWORK_INFO_INDEX = 0
+CFY_INFO_OUTPUT_FILE = "output.txt"
+
+CIDR_NETWORK_SEGMENT_INFO_INDEX = 0
+PACKET_LOST_INFO_INDEX = 0
+PACKET_TOTAL_INFO_INDEX = 1
+
+NUMBER_OF_DIGITS_FOR_AVG_TRANSFER = 0
+NUMBER_OF_DIGITS_FOR_AVG_BANDWIDTH = 0
+NUMBER_OF_DIGITS_FOR_AVG_JITTER = 3
+NUMBER_OF_DIGITS_FOR_AVG_PKT_LOSS = 1
+
+
+class Utilvnf(object):
+ """ Utility class of vrouter testcase """
+
+ logger = logging.getLogger(__name__)
+
+ def __init__(self):
+ self.username = ""
+ self.password = ""
+ self.auth_url = ""
+ self.tenant_name = ""
+ self.region_name = ""
+
+ data_dir = data_dir = CONST.__getattribute__('dir_router_data')
+
+ self.vnf_data_dir = data_dir
+ self.opnfv_vnf_data_dir = "opnfv-vnf-data/"
+ self.command_template_dir = "command_template/"
+ self.test_scenario_yaml = "test_scenario.yaml"
+ test_env_config_yaml_file = "test_env_config.yaml"
+ self.test_cmd_map_yaml_file = "test_cmd_map.yaml"
+ self.test_env_config_yaml = os.path.join(
+ self.vnf_data_dir,
+ self.opnfv_vnf_data_dir,
+ test_env_config_yaml_file)
+
+ self.blueprint_dir = "opnfv-vnf-vyos-blueprint/"
+ self.blueprint_file_name = "function-test-openstack-blueprint.yaml"
+
+ if not os.path.exists(self.vnf_data_dir):
+ os.makedirs(self.vnf_data_dir)
+
+ case_dir = pkg_resources.resource_filename(
+ 'functest', 'opnfv_tests/vnf/router')
+
+ config_file_name = CONST.__getattribute__(
+ 'vnf_{}_config'.format("vyos_vrouter"))
+
+ config_file = os.path.join(case_dir, config_file_name)
+
+ with open(config_file) as file_fd:
+ vrouter_config_yaml = yaml.safe_load(file_fd)
+ file_fd.close()
+
+ test_data = vrouter_config_yaml.get("test_data")
+
+ self.logger.debug("Downloading the test data.")
+ vrouter_data_path = self.vnf_data_dir + self.opnfv_vnf_data_dir
+
+ if not os.path.exists(vrouter_data_path):
+ Repo.clone_from(test_data['url'],
+ vrouter_data_path,
+ branch=test_data['branch'])
+
+ with open(self.test_env_config_yaml) as file_fd:
+ test_env_config_yaml = yaml.safe_load(file_fd)
+ file_fd.close()
+
+ self.image = test_env_config_yaml.get(
+ "general").get("images").get("vyos")
+ self.tester_image = test_env_config_yaml.get(
+ "general").get("images").get("tester_vm_os")
+
+ self.test_result_json_file = "test_result.json"
+ if os.path.isfile(self.test_result_json_file):
+ os.remove(self.test_result_json_file)
+ self.logger.debug("removed %s" % self.test_result_json_file)
+
+ def get_nova_client(self):
+ creds = self.get_nova_credentials()
+ loader = loading.get_plugin_loader('password')
+ auth = loader.load_from_options(**creds)
+ sess = session.Session(auth=auth)
+ nova_client = novaclient.Client(NOVA_CLIENT_API_VERSION, session=sess)
+
+ return nova_client
+
+ def set_credentials(self, username, password, auth_url,
+ tenant_name, region_name="RegionOne"):
+ self.username = username
+ self.password = password
+ self.auth_url = auth_url
+ self.tenant_name = tenant_name
+ self.region_name = region_name
+
+ def get_nova_credentials(self):
+ creds = {}
+ creds['username'] = self.username
+ creds['password'] = self.password
+ creds['auth_url'] = self.auth_url
+ creds['tenant_name'] = self.tenant_name
+ return creds
+
+ def get_address(self, server_name, network_name):
+ nova_client = self.get_nova_client()
+ servers_list = nova_client.servers.list()
+ server = None
+
+ for server in servers_list:
+ if server.name == server_name:
+ break
+
+ address = server.addresses[
+ network_name][NOVA_CILENT_NETWORK_INFO_INDEX]["addr"]
+
+ return address
+
+ def get_mac_address(self, server_name, network_name):
+ nova_client = self.get_nova_client()
+ servers_list = nova_client.servers.list()
+ server = None
+
+ for server in servers_list:
+ if server.name == server_name:
+ break
+
+ mac_address = server.addresses[network_name][
+ NOVA_CILENT_NETWORK_INFO_INDEX][
+ "OS-EXT-IPS-MAC:mac_addr"]
+
+ return mac_address
+
+ def reboot_vm(self, server_name):
+ nova_client = self.get_nova_client()
+ servers_list = nova_client.servers.list()
+ server = None
+
+ for server in servers_list:
+ if server.name == server_name:
+ break
+
+ server.reboot()
+
+ return
+
+ def delete_vm(self, server_name):
+ nova_client = self.get_nova_client()
+ servers_list = nova_client.servers.list()
+ server = None
+
+ for server in servers_list:
+ if server.name == server_name:
+ nova_client.servers.delete(server)
+ break
+
+ return
+
+ def get_blueprint_outputs(self, cfy_manager_ip, deployment_name):
+ url = "http://%s/deployments/%s/outputs" % (
+ cfy_manager_ip, deployment_name)
+
+ response = requests.get(
+ url,
+ auth=HTTPBasicAuth('admin', 'admin'),
+ headers={'Tenant': 'default_tenant'})
+
+ resp_data = response.json()
+ self.logger.debug(resp_data)
+ data = resp_data["outputs"]
+ return data
+
+ def get_blueprint_outputs_vnfs(self, cfy_manager_ip, deployment_name):
+ outputs = self.get_blueprint_outputs(cfy_manager_ip,
+ deployment_name)
+ vnfs = outputs["vnfs"]
+ vnf_list = []
+ for vnf_name in vnfs:
+ vnf_list.append(vnfs[vnf_name])
+ return vnf_list
+
+ def get_blueprint_outputs_networks(self, cfy_manager_ip, deployment_name):
+ outputs = self.get_blueprint_outputs(cfy_manager_ip,
+ deployment_name)
+ networks = outputs["networks"]
+ network_list = []
+ for network_name in networks:
+ network_list.append(networks[network_name])
+ return network_list
+
+ def request_vnf_reboot(self, vnf_info_list):
+ for vnf in vnf_info_list:
+ self.logger.debug("reboot the " + vnf["vnf_name"])
+ self.reboot_vm(vnf["vnf_name"])
+
+ def request_vm_delete(self, vnf_info_list):
+ for vnf in vnf_info_list:
+ self.logger.debug("delete the " + vnf["vnf_name"])
+ self.delete_vm(vnf["vnf_name"])
+
+ def get_vnf_info_list(self, cfy_manager_ip, topology_deploy_name,
+ target_vnf_name):
+ network_list = self.get_blueprint_outputs_networks(
+ cfy_manager_ip,
+ topology_deploy_name)
+ vnf_info_list = self.get_blueprint_outputs_vnfs(cfy_manager_ip,
+ topology_deploy_name)
+ for vnf in vnf_info_list:
+ vnf_name = vnf["vnf_name"]
+ vnf["os_type"] = self.image["os_type"]
+ vnf["user"] = self.image["user"]
+ vnf["pass"] = self.image["pass"]
+
+ if vnf_name == target_vnf_name:
+ vnf["target_vnf_flag"] = True
+ else:
+ vnf["target_vnf_flag"] = False
+
+ self.logger.debug("vnf name : " + vnf_name)
+ self.logger.debug(vnf_name + " floating ip address : " +
+ vnf["floating_ip"])
+
+ for network in network_list:
+ network_name = network["network_name"]
+ ip_address = self.get_address(vnf["vnf_name"],
+ network["network_name"])
+ vnf[network_name + "_ip"] = ip_address
+ mac = self.get_mac_address(vnf["vnf_name"],
+ network["network_name"])
+ vnf[network_name + "_mac"] = mac
+
+ self.logger.debug(network_name + "_ip of " + vnf["vnf_name"] +
+ " : " + vnf[network_name + "_ip"])
+ self.logger.debug(network_name + "_mac of " + vnf["vnf_name"] +
+ " : " + vnf[network_name + "_mac"])
+
+ return vnf_info_list
+
+ def get_target_vnf(self, vnf_info_list):
+ for vnf in vnf_info_list:
+ if vnf["target_vnf_flag"]:
+ return vnf
+
+ return None
+
+ def get_reference_vnf_list(self, vnf_info_list):
+ reference_vnf_list = []
+ for vnf in vnf_info_list:
+ if not vnf["target_vnf_flag"]:
+ reference_vnf_list.append(vnf)
+
+ return reference_vnf_list
+
+ def get_vnf_info(self, vnf_info_list, vnf_name):
+ for vnf in vnf_info_list:
+ if vnf["vnf_name"] == vnf_name:
+ return vnf
+
+ return None
+
+ def convert_functional_test_result(self, result_data_list):
+ result = {}
+ for result_data in result_data_list:
+ test_kind = result_data["test_kind"]
+ protocol = result_data["protocol"]
+ test_result_data = result_data["result"]
+
+ if test_kind not in result:
+ result[test_kind] = []
+
+ result[test_kind].append({protocol: test_result_data})
+
+ return {"Functional_test": result}
+
+ def write_result_data(self, result_data):
+ test_result = []
+ if not os.path.isfile(self.test_result_json_file):
+ file_fd = open(self.test_result_json_file, "w")
+ file_fd.close()
+ else:
+ file_fd = open(self.test_result_json_file, "r")
+ test_result = json.load(file_fd)
+ file_fd.close()
+
+ test_result.append(result_data)
+
+ file_fd = open(self.test_result_json_file, "w")
+ json.dump(test_result, file_fd)
+ file_fd.close()
+
+ def output_test_result_json(self):
+ if os.path.isfile(self.test_result_json_file):
+ file_fd = open(self.test_result_json_file, "r")
+ test_result = json.load(file_fd)
+ file_fd.close()
+ output_json_data = json.dumps(test_result,
+ sort_keys=True,
+ indent=4)
+ self.logger.debug("test_result %s" % output_json_data)
+ else:
+ self.logger.debug("Not found %s" % self.test_result_json_file)
+
+ def get_test_scenario(self, file_path):
+ test_scenario_file = open(file_path,
+ 'r')
+ test_scenario_yaml = yaml.safe_load(test_scenario_file)
+ test_scenario_file.close()
+ return test_scenario_yaml["test_scenario_list"]
diff --git a/functest/opnfv_tests/sdn/onos/teston/__init__.py b/functest/opnfv_tests/vnf/router/vnf_controller/__init__.py
index e69de29b..e69de29b 100644
--- a/functest/opnfv_tests/sdn/onos/teston/__init__.py
+++ b/functest/opnfv_tests/vnf/router/vnf_controller/__init__.py
diff --git a/functest/opnfv_tests/vnf/router/vnf_controller/checker.py b/functest/opnfv_tests/vnf/router/vnf_controller/checker.py
new file mode 100644
index 00000000..198a5ffc
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/vnf_controller/checker.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Okinawa Open Laboratory 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
+
+"""vrouter test result check module"""
+
+import json
+import logging
+import re
+
+from jinja2 import Environment, FileSystemLoader
+
+
+class Checker(object):
+ """vrouter test result check class"""
+
+ logger = logging.getLogger(__name__)
+
+ def __init__(self):
+ self.logger.debug("init checker")
+
+ def load_check_rule(self, rule_file_dir, rule_file_name, parameter):
+ loader = FileSystemLoader(rule_file_dir,
+ encoding='utf8')
+ env = Environment(loader=loader)
+ check_rule_template = env.get_template(rule_file_name)
+ check_rule = check_rule_template.render(parameter)
+ check_rule_data = json.loads(check_rule)
+ return check_rule_data
+
+ def regexp_information(self, response, rules):
+ status = False
+ result_data = {}
+
+ for rule in rules["rules"]:
+ result_data = {
+ "test_name": rule["description"],
+ "result": "NG"
+ }
+
+ match = re.search(rule["regexp"],
+ response)
+ rule["response"] = response
+ if match is None:
+ status = False
+ break
+
+ if not match.group(1) == rule["result"]:
+ status = False
+ else:
+ result_data["result"] = "OK"
+ status = True
+
+ return status, result_data
diff --git a/functest/opnfv_tests/vnf/router/vnf_controller/command_generator.py b/functest/opnfv_tests/vnf/router/vnf_controller/command_generator.py
new file mode 100644
index 00000000..98cb14cc
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/vnf_controller/command_generator.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Okinawa Open Laboratory 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
+
+"""command generator module for vrouter testing"""
+
+import logging
+from jinja2 import Environment, FileSystemLoader
+
+
+class CommandGenerator(object):
+ """command generator class for vrouter testing"""
+
+ logger = logging.getLogger(__name__)
+
+ def __init__(self):
+ self.logger.debug("init command generator")
+
+ def load_template(self, template_dir, template):
+ loader = FileSystemLoader(template_dir,
+ encoding='utf8')
+ env = Environment(loader=loader)
+ return env.get_template(template)
+
+ def command_create(self, template, parameter):
+ commands = template.render(parameter)
+ return commands.split('\n')
diff --git a/functest/opnfv_tests/vnf/router/vnf_controller/ssh_client.py b/functest/opnfv_tests/vnf/router/vnf_controller/ssh_client.py
new file mode 100644
index 00000000..c85a5735
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/vnf_controller/ssh_client.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Okinawa Open Laboratory 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
+
+"""ssh client module for vrouter testing"""
+
+import logging
+import paramiko
+import time
+import yaml
+
+from functest.opnfv_tests.vnf.router.utilvnf import Utilvnf
+
+RECEIVE_ROOP_WAIT = 1
+
+DEFAULT_CONNECT_TIMEOUT = 10
+DEFAULT_CONNECT_RETRY_COUNT = 10
+DEFAULT_SEND_TIMEOUT = 10
+
+
+class SshClient(object):
+ """ssh client class for vrouter testing"""
+
+ logger = logging.getLogger(__name__)
+
+ def __init__(self, ip_address, user, password=None, key_filename=None):
+ self.ip_address = ip_address
+ self.user = user
+ self.password = password
+ self.key_filename = key_filename
+ self.connected = False
+ self.shell = None
+
+ self.logger.setLevel(logging.INFO)
+
+ self.ssh = paramiko.SSHClient()
+ self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+
+ self.util = Utilvnf()
+ with open(self.util.test_env_config_yaml) as file_fd:
+ test_env_config_yaml = yaml.safe_load(file_fd)
+ file_fd.close()
+
+ self.ssh_revieve_buff = test_env_config_yaml.get("general").get(
+ "ssh_receive_buffer")
+
+ def connect(self, time_out=DEFAULT_CONNECT_TIMEOUT,
+ retrycount=DEFAULT_CONNECT_RETRY_COUNT):
+ while retrycount > 0:
+ try:
+ self.logger.info("SSH connect to %s.", self.ip_address)
+ self.ssh.connect(self.ip_address,
+ username=self.user,
+ password=self.password,
+ key_filename=self.key_filename,
+ timeout=time_out,
+ look_for_keys=False,
+ allow_agent=False)
+
+ self.logger.info("SSH connection established to %s.",
+ self.ip_address)
+
+ self.shell = self.ssh.invoke_shell()
+
+ while not self.shell.recv_ready():
+ time.sleep(RECEIVE_ROOP_WAIT)
+
+ self.shell.recv(self.ssh_revieve_buff)
+ break
+ except: # pylint: disable=broad-except
+ self.logger.info("SSH timeout for %s...", self.ip_address)
+ time.sleep(time_out)
+ retrycount -= 1
+
+ if retrycount == 0:
+ self.logger.error("Cannot establish connection to IP '%s'. " +
+ "Aborting",
+ self.ip_address)
+ self.connected = False
+ return self.connected
+
+ self.connected = True
+ return self.connected
+
+ def send(self, cmd, prompt, timeout=DEFAULT_SEND_TIMEOUT):
+ if self.connected is True:
+ self.shell.settimeout(timeout)
+ self.logger.debug("Commandset : '%s'", cmd)
+
+ try:
+ self.shell.send(cmd + '\n')
+ except: # pylint: disable=broad-except
+ self.logger.error("ssh send timeout : Command : '%s'", cmd)
+ return None
+
+ res_buff = ''
+ while not res_buff.endswith(prompt):
+ time.sleep(RECEIVE_ROOP_WAIT)
+ try:
+ res = self.shell.recv(self.ssh_revieve_buff)
+ except: # pylint: disable=broad-except
+ self.logger.error("ssh receive timeout : Command : '%s'",
+ cmd)
+ break
+
+ res_buff += res
+
+ self.logger.debug("Response : '%s'", res_buff)
+ return res_buff
+ else:
+ self.logger.error("Cannot connected to IP '%s'.", self.ip_address)
+ return None
+
+ def close(self):
+ if self.connected is True:
+ self.ssh.close()
+
+ def error_check(response, err_strs=["error",
+ "warn",
+ "unknown command",
+ "already exist"]):
+ for err in err_strs:
+ if err in response:
+ return False
+
+ return True
diff --git a/functest/opnfv_tests/vnf/router/vnf_controller/vm_controller.py b/functest/opnfv_tests/vnf/router/vnf_controller/vm_controller.py
new file mode 100644
index 00000000..cd228fe2
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/vnf_controller/vm_controller.py
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Okinawa Open Laboratory 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
+
+"""vm controll module"""
+
+import logging
+import os
+import time
+import yaml
+
+from functest.opnfv_tests.vnf.router.utilvnf import Utilvnf
+from functest.opnfv_tests.vnf.router.vnf_controller.command_generator import (
+ CommandGenerator)
+from functest.opnfv_tests.vnf.router.vnf_controller.ssh_client import (
+ SshClient)
+
+
+class VmController(object):
+ """vm controll class"""
+
+ logger = logging.getLogger(__name__)
+
+ def __init__(self, util_info):
+ self.logger.debug("initialize vm controller")
+ self.command_gen = CommandGenerator()
+ credentials = util_info["credentials"]
+
+ self.util = Utilvnf()
+ self.util.set_credentials(credentials["username"],
+ credentials["password"],
+ credentials["auth_url"],
+ credentials["tenant_name"],
+ credentials["region_name"])
+
+ with open(self.util.test_env_config_yaml) as file_fd:
+ test_env_config_yaml = yaml.safe_load(file_fd)
+ file_fd.close()
+
+ self.reboot_wait = test_env_config_yaml.get("general").get(
+ "reboot_wait")
+ self.command_wait = test_env_config_yaml.get("general").get(
+ "command_wait")
+ self.ssh_connect_timeout = test_env_config_yaml.get("general").get(
+ "ssh_connect_timeout")
+ self.ssh_connect_retry_count = test_env_config_yaml.get("general").get(
+ "ssh_connect_retry_count")
+
+ def command_gen_from_template(self, command_file_path, cmd_input_param):
+ (command_file_dir, command_file_name) = os.path.split(
+ command_file_path)
+ template = self.command_gen.load_template(command_file_dir,
+ command_file_name)
+ return self.command_gen.command_create(template,
+ cmd_input_param)
+
+ def config_vm(self, vm_info, test_cmd_file_path,
+ cmd_input_param, prompt_file_path):
+ ssh = self.connect_ssh_and_config_vm(vm_info,
+ test_cmd_file_path,
+ cmd_input_param,
+ prompt_file_path)
+ if ssh is None:
+ return False
+
+ ssh.close()
+
+ return True
+
+ def connect_ssh_and_config_vm(self, vm_info, test_cmd_file_path,
+ cmd_input_param, prompt_file_path):
+
+ key_filename = None
+ if "key_path" in vm_info:
+ key_filename = vm_info["key_path"]
+
+ ssh = SshClient(ip_address=vm_info["floating_ip"],
+ user=vm_info["user"],
+ password=vm_info["pass"],
+ key_filename=key_filename)
+
+ result = ssh.connect(self.ssh_connect_timeout,
+ self.ssh_connect_retry_count)
+ if not result:
+ self.logger.debug("try to vm reboot.")
+ self.util.reboot_vm(vm_info["vnf_name"])
+ time.sleep(self.reboot_wait)
+ result = ssh.connect(self.ssh_connect_timeout,
+ self.ssh_connect_retry_count)
+ if not result:
+ return None
+
+ (result, _) = self.command_create_and_execute(
+ ssh,
+ test_cmd_file_path,
+ cmd_input_param,
+ prompt_file_path)
+ if not result:
+ ssh.close()
+ return None
+
+ return ssh
+
+ def command_create_and_execute(self, ssh, test_cmd_file_path,
+ cmd_input_param, prompt_file_path):
+ prompt_file = open(prompt_file_path,
+ 'r')
+ prompt = yaml.safe_load(prompt_file)
+ prompt_file.close()
+ config_mode_prompt = prompt["config_mode"]
+
+ commands = self.command_gen_from_template(test_cmd_file_path,
+ cmd_input_param)
+ return self.command_list_execute(ssh,
+ commands,
+ config_mode_prompt)
+
+ def command_list_execute(self, ssh, command_list, prompt):
+ res_data_list = []
+ for command in command_list:
+ self.logger.debug("Command : " + command)
+ (res, res_data) = self.command_execute(ssh,
+ command,
+ prompt)
+ self.logger.debug("Response : " + res_data)
+ res_data_list.append(res_data)
+ if not res:
+ return res, res_data_list
+
+ time.sleep(self.command_wait)
+
+ return True, res_data_list
+
+ def command_execute(self, ssh, command, prompt):
+ res_data = ssh.send(command, prompt)
+ if res_data is None:
+ self.logger.info("retry send command : " + command)
+ res_data = ssh.send(command,
+ prompt)
+ if not ssh.error_check(res_data):
+ return False, res_data
+
+ return True, res_data
diff --git a/functest/opnfv_tests/vnf/router/vnf_controller/vnf_controller.py b/functest/opnfv_tests/vnf/router/vnf_controller/vnf_controller.py
new file mode 100644
index 00000000..814e9e33
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/vnf_controller/vnf_controller.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Okinawa Open Laboratory 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
+
+"""vrouter controll module"""
+
+import logging
+import os
+import prettytable
+import time
+import yaml
+
+from functest.opnfv_tests.vnf.router.utilvnf import Utilvnf
+from functest.opnfv_tests.vnf.router.vnf_controller.checker import Checker
+from functest.opnfv_tests.vnf.router.vnf_controller.ssh_client import (
+ SshClient)
+from functest.opnfv_tests.vnf.router.vnf_controller.vm_controller import (
+ VmController)
+
+
+class VnfController(object):
+ """vrouter controll class"""
+
+ logger = logging.getLogger(__name__)
+
+ def __init__(self, util_info):
+ self.logger.debug("init vnf controller")
+ self.util = Utilvnf()
+ self.vm_controller = VmController(util_info)
+
+ with open(self.util.test_env_config_yaml) as file_fd:
+ test_env_config_yaml = yaml.safe_load(file_fd)
+ file_fd.close()
+
+ self.cmd_wait = test_env_config_yaml.get("general").get("command_wait")
+ self.ssh_connect_timeout = test_env_config_yaml.get("general").get(
+ "ssh_connect_timeout")
+ self.ssh_connect_retry_count = test_env_config_yaml.get("general").get(
+ "ssh_connect_retry_count")
+
+ def config_vnf(self, source_vnf, destination_vnf, test_cmd_file_path,
+ parameter_file_path, prompt_file_path):
+ parameter_file = open(parameter_file_path,
+ 'r')
+ cmd_input_param = yaml.safe_load(parameter_file)
+ parameter_file.close()
+
+ cmd_input_param["macaddress"] = source_vnf["data_plane_network_mac"]
+ cmd_input_param["source_ip"] = source_vnf["data_plane_network_ip"]
+ cmd_input_param["destination_ip"] = destination_vnf[
+ "data_plane_network_ip"]
+
+ return self.vm_controller.config_vm(source_vnf,
+ test_cmd_file_path,
+ cmd_input_param,
+ prompt_file_path)
+
+ def result_check(self, target_vnf, reference_vnf,
+ check_rule_file_path_list, parameter_file_path,
+ prompt_file_path):
+
+ res_dict_data_list = []
+
+ parameter_file = open(parameter_file_path,
+ 'r')
+ cmd_input_param = yaml.safe_load(parameter_file)
+ parameter_file.close()
+
+ cmd_input_param["source_ip"] = target_vnf["data_plane_network_ip"]
+ cmd_input_param["destination_ip"] = reference_vnf[
+ "data_plane_network_ip"]
+
+ prompt_file = open(prompt_file_path,
+ 'r')
+ prompt = yaml.safe_load(prompt_file)
+ prompt_file.close()
+ terminal_mode_prompt = prompt["terminal_mode"]
+
+ ssh = SshClient(target_vnf["floating_ip"],
+ target_vnf["user"],
+ target_vnf["pass"])
+
+ result = ssh.connect(self.ssh_connect_timeout,
+ self.ssh_connect_retry_count)
+ if not result:
+ return False, res_dict_data_list
+
+ checker = Checker()
+
+ res_table = prettytable.PrettyTable(
+ header_style='upper', padding_width=5,
+ field_names=['test item', 'result'])
+
+ status = True
+ res_data_list = []
+ for check_rule_file_path in check_rule_file_path_list:
+ (check_rule_dir, check_rule_file) = os.path.split(
+ check_rule_file_path)
+ check_rules = checker.load_check_rule(check_rule_dir,
+ check_rule_file,
+ cmd_input_param)
+ (res, res_data) = self.vm_controller.command_execute(
+ ssh,
+ check_rules["command"],
+ terminal_mode_prompt)
+ res_data_list.append(res_data)
+ if not res:
+ status = False
+ break
+
+ (res, res_dict_data) = checker.regexp_information(res_data,
+ check_rules)
+ res_dict_data_list.append(res_dict_data)
+ res_table.add_row([res_dict_data["test_name"],
+ res_dict_data["result"]])
+ if not res:
+ status = False
+
+ time.sleep(self.cmd_wait)
+
+ ssh.close()
+
+ self.logger.info("Test result:\n\n%s\n", res_table.get_string())
+
+ self.output_check_result_detail_data(res_data_list)
+
+ return status, res_dict_data_list
+
+ def output_check_result_detail_data(self, res_data_list):
+ for res_data in res_data_list:
+ self.logger.debug(res_data)
diff --git a/functest/opnfv_tests/vnf/router/vrouter_base.py b/functest/opnfv_tests/vnf/router/vrouter_base.py
new file mode 100644
index 00000000..a534f1f2
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/vrouter_base.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Okinawa Open Laboratory 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
+
+"""vrouter testing base class module"""
+
+import datetime
+import json
+import logging
+import os
+import pkg_resources
+import time
+
+import functest.core.vnf as vnf
+from functest.utils.constants import CONST
+from functest.opnfv_tests.vnf.router.test_controller import function_test_exec
+from functest.opnfv_tests.vnf.router.utilvnf import Utilvnf
+
+__author__ = "Shuya Nakama <shuya.nakama@okinawaopenlabs.org>"
+
+REBOOT_WAIT = 30
+
+
+class VrouterOnBoardingBase(vnf.VnfOnBoarding):
+ """vrouter testing base class"""
+
+ def __init__(self, **kwargs):
+ self.logger = logging.getLogger(__name__)
+ super(VrouterOnBoardingBase, self).__init__(**kwargs)
+ self.case_dir = pkg_resources.resource_filename(
+ 'functest', 'opnfv_tests/vnf/router')
+ self.data_dir = CONST.__getattribute__('dir_router_data')
+ self.result_dir = os.path.join(CONST.__getattribute__('dir_results'),
+ self.case_name)
+ self.util = Utilvnf()
+ self.util_info = {}
+
+ self.vnf_list = []
+
+ if not os.path.exists(self.data_dir):
+ os.makedirs(self.data_dir)
+ if not os.path.exists(self.result_dir):
+ os.makedirs(self.result_dir)
+
+ def test_vnf(self):
+ """vrouter test execution"""
+ result = False
+ test_result_data_list = []
+ test_scenario_file_path = os.path.join(self.case_dir,
+ self.util.test_scenario_yaml)
+ test_scenario_list = self.util.get_test_scenario(
+ test_scenario_file_path)
+ for test_scenario in test_scenario_list:
+ if test_scenario["test_type"] == "function_test":
+ function_test_list = test_scenario["function_test_list"]
+ for function_test in function_test_list:
+ test_list = function_test["test_list"]
+ target_vnf_name = function_test["target_vnf_name"]
+ for test_info in test_list:
+ self.logger.info(test_info["protocol"] + " " +
+ test_info["test_kind"] +
+ " test.")
+ (result, result_data) = self.function_test_vrouter(
+ target_vnf_name,
+ test_info)
+ test_result_data_list.append(result_data)
+ if not result:
+ break
+
+ self.util.request_vm_delete(self.vnf_list)
+
+ test_result_data = json.dumps(test_result_data_list, indent=4)
+
+ return result, test_result_data
+
+ def function_test_vrouter(self, target_vnf_name, test_info):
+ """function test execution"""
+
+ test_protocol = test_info["protocol"]
+ test_list = test_info[test_protocol]
+
+ vnf_info_list = self.get_vnf_info_list(target_vnf_name)
+ self.vnf_list = vnf_info_list
+
+ self.logger.debug("request vnf's reboot.")
+ self.util.request_vnf_reboot(vnf_info_list)
+ time.sleep(REBOOT_WAIT)
+
+ target_vnf = self.util.get_target_vnf(vnf_info_list)
+
+ reference_vnf_list = self.util.get_reference_vnf_list(vnf_info_list)
+
+ test_exec = function_test_exec.FunctionTestExec(self.util_info)
+
+ # start test
+ start_time_ts = time.time()
+ self.logger.info("vRouter test Start Time:'%s'", (
+ datetime.datetime.fromtimestamp(start_time_ts).strftime(
+ '%Y-%m-%d %H:%M:%S')))
+
+ (result, test_result_data) = test_exec.run(target_vnf,
+ reference_vnf_list,
+ test_info,
+ test_list)
+
+ end_time_ts = time.time()
+ duration = round(end_time_ts - start_time_ts, 1)
+ self.logger.info("vRouter test duration :'%s'", duration)
+
+ return result, test_result_data
+
+ def get_vnf_info_list(self, target_vnf_name):
+ vnf_info_list = []
+ return vnf_info_list
diff --git a/functest/opnfv_tests/vnf/router/vyos_vrouter.py b/functest/opnfv_tests/vnf/router/vyos_vrouter.py
deleted file mode 100644
index 5654278d..00000000
--- a/functest/opnfv_tests/vnf/router/vyos_vrouter.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2017 Okinawa Open Laboratory
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-import functest.core.feature as base
-import json
-import os
-
-RESULT_DETAILS_FILE = "test_result.json"
-
-
-class VrouterVnf(base.Feature):
- def __init__(self, **kwargs):
- kwargs["repo"] = 'dir_repo_vrouter'
- if "case_name" not in kwargs:
- kwargs["case_name"] = "vyos_vrouter"
- super(VrouterVnf, self).__init__(**kwargs)
- self.cmd = 'cd %s && ./run.sh' % self.repo
-
- def set_result_details(self):
- filepath = os.path.join(self.repo, RESULT_DETAILS_FILE)
- if os.path.exists(filepath):
- f = open(filepath, 'r')
- self.details = json.load(f)
- f.close()
-
- def log_results(self):
- if self.result == 'PASS':
- self.set_result_details()
- super(VrouterVnf, self).log_results()
diff --git a/functest/tests/unit/utils/test_functest_utils.py b/functest/tests/unit/utils/test_functest_utils.py
index cd3693c7..17fb4c1f 100644
--- a/functest/tests/unit/utils/test_functest_utils.py
+++ b/functest/tests/unit/utils/test_functest_utils.py
@@ -97,42 +97,6 @@ class FunctestUtilsTesting(unittest.TestCase):
m.assert_called_once_with(dest, 'wb')
self.assertTrue(mock_sh.called)
- @mock.patch('functest.utils.functest_utils.logger.error')
- def test_get_installer_type_failed(self, mock_logger_error):
- with mock.patch.dict(os.environ,
- {},
- clear=True):
- self.assertEqual(functest_utils.get_installer_type(),
- "Unknown_installer")
- mock_logger_error.assert_called_once_with("Impossible to retrieve"
- " the installer type")
-
- def test_get_installer_type_default(self):
- with mock.patch.dict(os.environ,
- {'INSTALLER_TYPE': 'test_installer'},
- clear=True):
- self.assertEqual(functest_utils.get_installer_type(),
- self.installer)
-
- @mock.patch('functest.utils.functest_utils.logger.info')
- def test_get_scenario_failed(self, mock_logger_info):
- with mock.patch.dict(os.environ,
- {},
- clear=True):
- self.assertEqual(functest_utils.get_scenario(),
- "os-nosdn-nofeature-noha")
- mock_logger_info.assert_called_once_with("Impossible to retrieve "
- "the scenario.Use "
- "default "
- "os-nosdn-nofeature-noha")
-
- def test_get_scenario_default(self):
- with mock.patch.dict(os.environ,
- {'DEPLOY_SCENARIO': 'test_scenario'},
- clear=True):
- self.assertEqual(functest_utils.get_scenario(),
- self.scenario)
-
def test_get_version_daily_job(self):
CONST.__setattr__('BUILD_TAG', self.build_tag)
self.assertEqual(functest_utils.get_version(), self.version)
@@ -154,10 +118,9 @@ class FunctestUtilsTesting(unittest.TestCase):
CONST.__setattr__('results_test_db_url', self.db_url)
CONST.__setattr__('BUILD_TAG', self.build_tag)
CONST.__setattr__('NODE_NAME', self.node_name)
- with mock.patch('functest.utils.functest_utils.get_scenario',
- return_value=self.scenario), \
- mock.patch('functest.utils.functest_utils.get_version',
- return_value=self.version):
+ CONST.__setattr__('DEPLOY_SCENARIO', self.scenario)
+ with mock.patch('functest.utils.functest_utils.get_version',
+ return_value=self.version):
functest_utils.logger_test_results(self.project, self.case_name,
self.status, self.details)
mock_logger_info.assert_called_once_with(
diff --git a/functest/opnfv_tests/sdn/onos/teston/adapters/__init__.py b/functest/tests/unit/vnf/router/__init__.py
index e69de29b..e69de29b 100644
--- a/functest/opnfv_tests/sdn/onos/teston/adapters/__init__.py
+++ b/functest/tests/unit/vnf/router/__init__.py
diff --git a/functest/tests/unit/vnf/router/test_cloudify_vrouter.py b/functest/tests/unit/vnf/router/test_cloudify_vrouter.py
new file mode 100644
index 00000000..7f2091be
--- /dev/null
+++ b/functest/tests/unit/vnf/router/test_cloudify_vrouter.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Okinawa Open Laboratory and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import logging
+import unittest
+
+import mock
+
+from functest.core import vnf
+from functest.opnfv_tests.vnf.router import cloudify_vrouter
+
+from snaps.openstack.os_credentials import OSCreds
+
+
+class CloudifyVrouterTesting(unittest.TestCase):
+
+ def setUp(self):
+
+ self.tenant = 'cloudify_vrouter'
+ self.creds = {'username': 'user',
+ 'password': 'pwd'}
+ self.orchestrator = {'name': 'cloudify',
+ 'version': '4.0',
+ 'object': 'foo',
+ 'requirements': {'flavor': {'name': 'm1.medium',
+ 'ram_min': 4096},
+ 'os_image': 'manager_4.0'}}
+
+ self.vnf = {'name': 'vrouter',
+ 'descriptor': {'version': '100',
+ 'file_name': 'function-test-' +
+ 'openstack-blueprint.yaml',
+ 'name': 'vrouter-opnfv',
+ 'url': 'https://foo',
+ 'requirements': {'flavor':
+ {'name': 'm1.medium',
+ 'ram_min': 2048}}}}
+
+ with mock.patch('functest.opnfv_tests.vnf.router.cloudify_vrouter.'
+ 'os.makedirs'), \
+ mock.patch('functest.opnfv_tests.vnf.router.cloudify_vrouter.'
+ 'get_config', return_value={
+ 'tenant_images': 'foo',
+ 'orchestrator': self.orchestrator,
+ 'vnf': self.vnf,
+ 'vnf_test_suite': '',
+ 'version': 'whatever'}):
+
+ self.router_vnf = cloudify_vrouter.CloudifyVrouter()
+
+ self.images = {'image1': 'url1',
+ 'image2': 'url2'}
+ self.details = {'orchestrator': {'status': 'PASS', 'duration': 120},
+ 'vnf': {},
+ 'test_vnf': {}}
+
+ @mock.patch('functest.core.vnf.os_utils.get_keystone_client',
+ return_value='test')
+ @mock.patch('functest.core.vnf.os_utils.get_or_create_tenant_for_vnf',
+ return_value=True)
+ @mock.patch('functest.core.vnf.os_utils.get_or_create_user_for_vnf',
+ return_value=True)
+ @mock.patch('functest.core.vnf.os_utils.get_credentials',
+ return_value={'auth_url': 'test/v1'})
+ @mock.patch('snaps.openstack.create_image.OpenStackImage.create')
+ def test_prepare_default(self, *args):
+ self.assertIsNone(self.router_vnf.prepare())
+ args[4].assert_called_once_with()
+
+ @mock.patch('functest.core.vnf.os_utils.get_keystone_client',
+ return_value='test')
+ @mock.patch('functest.core.vnf.os_utils.get_or_create_tenant_for_vnf',
+ return_value=True)
+ @mock.patch('functest.core.vnf.os_utils.get_or_create_user_for_vnf',
+ return_value=True)
+ @mock.patch('functest.core.vnf.os_utils.get_credentials',
+ return_value={'auth_url': 'test/no_v'})
+ @mock.patch('snaps.openstack.create_image.OpenStackImage.create')
+ def test_prepare_bad_auth_url(self, *args):
+ with self.assertRaises(Exception):
+ self.router_vnf.image_creator(
+ OSCreds(username='user', password='pass', auth_url='url',
+ project_name='project', identity_api_version=3),
+ mock.Mock())
+ args[0].assert_not_called()
+
+ def test_prepare_missing_param(self):
+ with self.assertRaises(vnf.VnfPreparationException):
+ self.router_vnf.prepare()
+
+ @mock.patch('functest.core.vnf.os_utils.get_keystone_client',
+ side_effect=Exception)
+ def test_prepare_keystone_exception(self, *args):
+ with self.assertRaises(vnf.VnfPreparationException):
+ self.router_vnf.prepare()
+ args[0].assert_called_once_with()
+
+ @mock.patch('functest.core.vnf.os_utils.get_keystone_client',
+ return_value='test')
+ @mock.patch('functest.core.vnf.os_utils.get_or_create_tenant_for_vnf',
+ side_effect=Exception)
+ def test_prepare_tenant_exception(self, *args):
+ with self.assertRaises(vnf.VnfPreparationException):
+ self.router_vnf.prepare()
+ args[1].assert_called_once_with()
+
+ @mock.patch('functest.core.vnf.os_utils.get_keystone_client',
+ return_value='test')
+ @mock.patch('functest.core.vnf.os_utils.get_or_create_tenant_for_vnf',
+ return_value=True)
+ @mock.patch('functest.core.vnf.os_utils.get_or_create_user_for_vnf',
+ side_effect=Exception)
+ def test_prepare_user_exception(self, *args):
+ with self.assertRaises(vnf.VnfPreparationException):
+ self.router_vnf.prepare()
+ args[2].assert_called_once_with()
+
+ @mock.patch('functest.core.vnf.os_utils.get_keystone_client',
+ return_value='test')
+ @mock.patch('functest.core.vnf.os_utils.get_or_create_tenant_for_vnf',
+ return_value=True)
+ @mock.patch('functest.core.vnf.os_utils.get_or_create_user_for_vnf',
+ return_value=True)
+ @mock.patch('functest.core.vnf.os_utils.get_credentials',
+ side_effect=Exception)
+ def test_prepare_credentials_exception(self, *args):
+ with self.assertRaises(vnf.VnfPreparationException):
+ self.router_vnf.prepare()
+ args[0].assert_called_once_with()
+
+
+if __name__ == "__main__":
+ logging.disable(logging.CRITICAL)
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/vnf/router/test_vrouter_base.py b/functest/tests/unit/vnf/router/test_vrouter_base.py
new file mode 100644
index 00000000..def201d1
--- /dev/null
+++ b/functest/tests/unit/vnf/router/test_vrouter_base.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Okinawa Open Laboratory and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import logging
+import unittest
+
+import mock
+
+from functest.opnfv_tests.vnf.router import vrouter_base
+
+
+class VrouterOnBoardingBaseTesting(unittest.TestCase):
+
+ def setUp(self):
+ with mock.patch('functest.opnfv_tests.vnf.router.cloudify_vrouter.'
+ 'os.makedirs'):
+ self.vrouter_vnf = vrouter_base.VrouterOnBoardingBase()
+
+
+if __name__ == "__main__":
+ logging.disable(logging.CRITICAL)
+ unittest.main(verbosity=2)
diff --git a/functest/utils/functest_utils.py b/functest/utils/functest_utils.py
index 5bf3adb6..e4062373 100644
--- a/functest/utils/functest_utils.py
+++ b/functest/utils/functest_utils.py
@@ -68,33 +68,6 @@ def download_url(url, dest_path):
# CI UTILS
#
# -----------------------------------------------------------
-def get_installer_type():
- """
- Get installer type (fuel, apex, joid, compass)
- """
- try:
- installer = os.environ['INSTALLER_TYPE']
- except KeyError:
- logger.error("Impossible to retrieve the installer type")
- installer = "Unknown_installer"
-
- return installer
-
-
-def get_scenario():
- """
- Get scenario
- """
- try:
- scenario = os.environ['DEPLOY_SCENARIO']
- except KeyError:
- logger.info("Impossible to retrieve the scenario."
- "Use default os-nosdn-nofeature-noha")
- scenario = "os-nosdn-nofeature-noha"
-
- return scenario
-
-
def get_version():
"""
Get version
@@ -122,7 +95,7 @@ def logger_test_results(project, case_name, status, details):
Format test case results for the logger
"""
pod_name = CONST.__getattribute__('NODE_NAME')
- scenario = get_scenario()
+ scenario = CONST.__getattribute__('DEPLOY_SCENARIO')
version = get_version()
build_tag = CONST.__getattribute__('BUILD_TAG')
db_url = CONST.__getattribute__("results_test_db_url")
diff --git a/requirements.txt b/requirements.txt
index 0cc20eae..234be168 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -22,6 +22,7 @@ openbaton-cli
cloudify_rest_client
Flask!=0.11,<1.0,>=0.10 # BSD
Flask-RESTful>=0.3.5 # BSD
+IPy
mock>=2.0 # BSD
iniparse==0.4
PrettyTable<0.8,>=0.7.1 # BSD
diff --git a/setup.cfg b/setup.cfg
index 89aa033e..d39d648f 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -14,7 +14,6 @@ scripts =
console_scripts =
functest = functest.cli.cli_base:cli
functest_odl = functest.opnfv_tests.sdn.odl.odl:main
- functest_onos_sfc = functest.opnfv_tests.sdn.onos.sfc.sfc:main
functest_refstack_client = functest.opnfv_tests.openstack.refstack_client.refstack_client:main
functest_tempest_conf = functest.opnfv_tests.openstack.refstack_client.tempest_conf:main
openstack_snapshot = functest.utils.openstack_snapshot:main
diff --git a/upper-constraints.txt b/upper-constraints.txt
index 74d363c5..fae94270 100644
--- a/upper-constraints.txt
+++ b/upper-constraints.txt
@@ -14,3 +14,4 @@ robotframework-httplibrary===0.4.2
robotframework-requests===0.4.7
robotframework-sshlibrary===2.1.3;python_version=='2.7'
rally===0.9.1
+IPy===0.83