aboutsummaryrefslogtreecommitdiffstats
path: root/functest
diff options
context:
space:
mode:
Diffstat (limited to 'functest')
-rwxr-xr-xfunctest/ci/config_functest.yaml12
-rwxr-xr-xfunctest/ci/config_patch.yaml6
-rwxr-xr-xfunctest/ci/exec_test.sh6
-rwxr-xr-xfunctest/ci/prepare_env.py58
-rwxr-xr-xfunctest/ci/testcases.yaml27
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template2
-rw-r--r--functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template2
-rw-r--r--functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt19
-rw-r--r--functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt4
-rw-r--r--functest/opnfv_tests/openstack/tempest/tempest.py6
-rw-r--r--functest/opnfv_tests/sdn/onos/__init__.py0
-rw-r--r--functest/opnfv_tests/sdn/onos/onos.py225
-rwxr-xr-xfunctest/opnfv_tests/sdn/onos/teston/onos.py261
-rw-r--r--functest/tests/unit/utils/test_openstack_utils.py58
-rwxr-xr-x[-rw-r--r--]functest/utils/config.py20
-rw-r--r--functest/utils/functest_constants.py9
-rwxr-xr-xfunctest/utils/openstack_utils.py87
17 files changed, 430 insertions, 372 deletions
diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml
index 489c395f..402e2999 100755
--- a/functest/ci/config_functest.yaml
+++ b/functest/ci/config_functest.yaml
@@ -5,8 +5,8 @@ general:
dir_odl: functest/opnfv_tests/sdn/odl
rally: functest/opnfv_tests/openstack/rally
tempest_cases: functest/opnfv_tests/openstack/tempest/custom_tests
- dir_onos: functest/opnfv_tests/sdn/onos/teston
- dir_onos_sfc: functest/opnfv_tests/sdn/onos/sfc
+ onos: functest/opnfv_tests/sdn/onos/teston
+ onos_sfc: functest/opnfv_tests/sdn/onos/sfc
# Absolute path
home: /home/opnfv
@@ -18,7 +18,7 @@ general:
repo_vims_test: /home/opnfv/repos/vnfs/vims-test
repo_sdnvpn: /home/opnfv/repos/sdnvpn
repo_sfc: /home/opnfv/repos/sfc
- dir_repo_onos: /home/opnfv/repos/onos
+ repo_onos: /home/opnfv/repos/onos
repo_promise: /home/opnfv/repos/promise
repo_netready: /home/opnfv/repos/netready
repo_barometer: /home/opnfv/repos/barometer
@@ -43,8 +43,8 @@ general:
creds: /home/opnfv/functest/conf/openstack.creds
snapshot_file: /home/opnfv/functest/conf/openstack_snapshot.yaml
- image_name: Cirros-0.3.4
- image_file_name: cirros-0.3.4-x86_64-disk.img
+ image_name: Cirros-0.3.5
+ image_file_name: cirros-0.3.5-x86_64-disk.img
image_disk_format: qcow2
image_username: cirros
image_password: cubswin:)
@@ -67,7 +67,7 @@ general:
testcases_yaml: /home/opnfv/repos/functest/functest/ci/testcases.yaml
healthcheck:
- disk_image: /home/opnfv/functest/data/cirros-0.3.4-x86_64-disk.img
+ disk_image: /home/opnfv/functest/data/cirros-0.3.5-x86_64-disk.img
disk_format: qcow2
wait_time: 60
diff --git a/functest/ci/config_patch.yaml b/functest/ci/config_patch.yaml
index 46064a07..d984a3f4 100755
--- a/functest/ci/config_patch.yaml
+++ b/functest/ci/config_patch.yaml
@@ -1,12 +1,12 @@
lxd:
general:
openstack:
- image_name: Cirros-0.3.4
- image_file_name: cirros-0.3.4-x86_64-lxc.tar.gz
+ image_name: Cirros-0.3.5
+ image_file_name: cirros-0.3.5-x86_64-lxc.tar.gz
image_disk_format: raw
healthcheck:
- disk_image: /home/opnfv/functest/data/cirros-0.3.4-x86_64-lxc.tar.gz
+ disk_image: /home/opnfv/functest/data/cirros-0.3.5-x86_64-lxc.tar.gz
disk_format: raw
fdio:
general:
diff --git a/functest/ci/exec_test.sh b/functest/ci/exec_test.sh
index aa0cfaf7..6f776101 100755
--- a/functest/ci/exec_test.sh
+++ b/functest/ci/exec_test.sh
@@ -94,12 +94,6 @@ function run_test(){
--osusername ${OS_USERNAME} \
${args}
;;
- "onos")
- python ${FUNCTEST_TEST_DIR}/sdn/onos/teston/onos.py
- ;;
- "onos_sfc")
- python ${FUNCTEST_TEST_DIR}/sdn/onos/teston/onos.py -t sfc
- ;;
"ovno")
# suite under rewritting for colorado
# no need to run anything until refactoring done
diff --git a/functest/ci/prepare_env.py b/functest/ci/prepare_env.py
index f5bae6a0..724ea14d 100755
--- a/functest/ci/prepare_env.py
+++ b/functest/ci/prepare_env.py
@@ -31,6 +31,7 @@ logger = ft_logger.Logger("prepare_env").getLogger()
handler = None
# set the architecture to default
pod_arch = None
+arch_filter = ['aarch64']
CONFIG_FUNCTEST_PATH = CONST.CONFIG_FUNCTEST_YAML
CONFIG_PATCH_PATH = os.path.join(os.path.dirname(
@@ -115,24 +116,28 @@ def get_deployment_handler():
'functest/ci/installer_params.yaml')
if (CONST.INSTALLER_IP and CONST.INSTALLER_TYPE and
CONST.INSTALLER_TYPE in opnfv_constants.INSTALLERS):
- installer_params = ft_utils.get_parameter_from_yaml(
- CONST.INSTALLER_TYPE, installer_params_yaml)
-
- user = installer_params.get('user', None)
- password = installer_params.get('password', None)
- pkey = installer_params.get('pkey', None)
-
try:
- handler = factory.Factory.get_handler(
- installer=CONST.INSTALLER_TYPE,
- installer_ip=CONST.INSTALLER_IP,
- installer_user=user,
- installer_pwd=password,
- pkey_file=pkey)
- if handler:
- pod_arch = handler.get_arch()
- except Exception as e:
- logger.debug("Cannot get deployment information. %s" % e)
+ installer_params = ft_utils.get_parameter_from_yaml(
+ CONST.INSTALLER_TYPE, installer_params_yaml)
+ except ValueError as e:
+ logger.debug('Printing deployment info is not supported for %s' %
+ CONST.INSTALLER_TYPE)
+ logger.debug(e)
+ else:
+ user = installer_params.get('user', None)
+ password = installer_params.get('password', None)
+ pkey = installer_params.get('pkey', None)
+ try:
+ handler = factory.Factory.get_handler(
+ installer=CONST.INSTALLER_TYPE,
+ installer_ip=CONST.INSTALLER_IP,
+ installer_user=user,
+ installer_pwd=password,
+ pkey_file=pkey)
+ if handler:
+ pod_arch = handler.get_arch()
+ except Exception as e:
+ logger.debug("Cannot get deployment information. %s" % e)
def create_directories():
@@ -196,8 +201,7 @@ def source_rc_file():
raise Exception("The file %s is empty." % CONST.openstack_creds)
logger.info("Sourcing the OpenStack RC file...")
- os_utils.source_credentials(
- CONST.openstack_creds)
+ os_utils.source_credentials(CONST.openstack_creds)
for key, value in os.environ.iteritems():
if re.search("OS_", key):
if key == 'OS_AUTH_URL':
@@ -210,10 +214,15 @@ def source_rc_file():
CONST.OS_PASSWORD = value
-def patch_config_file(patch_file_path, arch_filter=None):
- if arch_filter and pod_arch not in arch_filter:
- return
+def patch_config_file():
+ patch_file(CONFIG_PATCH_PATH)
+
+ if pod_arch and pod_arch in arch_filter:
+ patch_file(CONFIG_AARCH64_PATCH_PATH)
+
+def patch_file(patch_file_path):
+ logger.debug('Updating file: %s', patch_file_path)
with open(patch_file_path) as f:
patch_file = yaml.safe_load(f)
@@ -250,7 +259,7 @@ def verify_deployment():
def install_rally():
print_separator()
- if 'aarch64' in pod_arch:
+ if pod_arch and pod_arch in arch_filter:
logger.info("Apply aarch64 specific to rally config...")
with open(RALLY_AARCH64_PATCH_PATH, "r") as f:
rally_patch_conf = f.read()
@@ -350,8 +359,7 @@ def main(**kwargs):
get_deployment_handler()
create_directories()
source_rc_file()
- patch_config_file(CONFIG_PATCH_PATH)
- patch_config_file(CONFIG_AARCH64_PATCH_PATH, 'aarch64')
+ patch_config_file()
verify_deployment()
install_rally()
install_tempest()
diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml
index f8bbe9b7..722e8796 100755
--- a/functest/ci/testcases.yaml
+++ b/functest/ci/testcases.yaml
@@ -78,7 +78,7 @@ tiers:
over a private network.
dependencies:
installer: ''
- scenario: '^((?!bgpvpn|odl_l3).)*$'
+ scenario: '^((?!odl_l3).)*$'
run:
module: 'functest.opnfv_tests.openstack.vping.vping_ssh'
class: 'VPingSSH'
@@ -125,7 +125,7 @@ tiers:
Rally suite in smoke mode.
dependencies:
installer: ''
- scenario: '^((?!bgpvpn).)*$'
+ scenario: ''
run:
module: 'functest.opnfv_tests.openstack.rally.rally'
class: 'RallySanity'
@@ -184,7 +184,9 @@ tiers:
dependencies:
installer: ''
scenario: 'onos'
-
+ run:
+ module: 'functest.opnfv_tests.sdn.onos.onos'
+ class: 'Onos'
-
name: snaps_smoke
@@ -319,6 +321,9 @@ tiers:
dependencies:
installer: ''
scenario: 'onos-sfc'
+ run:
+ module: 'functest.opnfv_tests.sdn.onos.onos'
+ class: 'OnosSfc'
-
name: parser
criteria: 'ret == 0'
@@ -423,6 +428,22 @@ tiers:
run:
module: 'functest.opnfv_tests.openstack.tempest.tempest'
class: 'TempestDefcore'
+ -
+ name: tempest_custom
+ criteria: 'success_rate == 100%'
+ blocking: false
+ description: >-
+ The test case allows running a customized list of tempest
+ test cases defined in a file under
+ <dir_functest_repo>/functest/opnfv_tests/openstack/
+ /tempest/custom_tests/test_list.txt
+ The file is empty and can be customized with the desired tests.
+ dependencies:
+ installer: 'unknown'
+ scenario: 'unknown'
+ run:
+ module: 'functest.opnfv_tests.openstack.tempest.tempest'
+ class: 'TempestCustom'
# -
# name: rally_full
# criteria: 'success_rate >= 90%'
diff --git a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
index 909f45d2..ed5e61fe 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
+++ b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
@@ -7,7 +7,7 @@ parameters:
default: public
image:
type: string
- default: cirros-0.3.4-x86_64-uec
+ default: cirros-0.3.5-x86_64-uec
flavor:
type: string
default: m1.tiny
diff --git a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
index 826ca9da..116b5bb6 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
+++ b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
@@ -4,7 +4,7 @@ parameters:
# set all correct defaults for parameters before launch test
image:
type: string
- default: cirros-0.3.4-x86_64-uec
+ default: cirros-0.3.5-x86_64-uec
flavor:
type: string
default: m1.tiny
diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
index 0a4256ce..fcdfe225 100644
--- a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
+++ b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
@@ -1,22 +1,3 @@
--
- scenarios:
- - os-odl_l2-bgpvpn-ha
- - os-odl_l2-bgpvpn-noha
- installers:
- - fuel
- - apex
- tests:
- - tempest.api.compute.servers.test_create_server.ServersTestJSON.test_list_servers
- - tempest.api.compute.servers.test_create_server.ServersTestJSON.test_verify_server_details
- - tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers
- - tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_server_details
- - tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_hard
- - tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_create_list_show_update_delete_floating_ip
- - tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_create_floating_ip_specifying_a_fixed_ip_address
- - tempest.scenario.test_network_basic_ops.TestNetworkBasicOps.test_network_basic_ops
- - tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops
- - tempest.scenario.test_volume_boot_pattern.TestVolumeBootPattern.test_volume_boot_pattern
- - tempest.scenario.test_volume_boot_pattern.TestVolumeBootPatternV2.test_volume_boot_pattern
-
scenarios:
diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt b/functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt
new file mode 100644
index 00000000..ac4e3728
--- /dev/null
+++ b/functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt
@@ -0,0 +1,4 @@
+# This is an empty file to be filled up with the desired tempest test cases
+# Examples:
+#tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops
+#tempest.scenario.test_network_basic_ops.TestNetworkBasicOps.test_network_basic_ops \ No newline at end of file
diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py
index 37b5c0ee..4c96500d 100644
--- a/functest/opnfv_tests/openstack/tempest/tempest.py
+++ b/functest/opnfv_tests/openstack/tempest/tempest.py
@@ -324,11 +324,11 @@ class TempestMultisite(TempestCommon):
class TempestCustom(TempestCommon):
- def __init__(self, mode, option):
+ def __init__(self):
TempestCommon.__init__(self)
self.case_name = "tempest_custom"
- self.MODE = mode
- self.OPTION = option
+ self.MODE = "custom"
+ self.OPTION = "--concurrency 1"
class TempestDefcore(TempestCommon):
diff --git a/functest/opnfv_tests/sdn/onos/__init__.py b/functest/opnfv_tests/sdn/onos/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/functest/opnfv_tests/sdn/onos/__init__.py
diff --git a/functest/opnfv_tests/sdn/onos/onos.py b/functest/opnfv_tests/sdn/onos/onos.py
new file mode 100644
index 00000000..8bc73832
--- /dev/null
+++ b/functest/opnfv_tests/sdn/onos/onos.py
@@ -0,0 +1,225 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 HUAWEI TECHNOLOGIES CO.,LTD and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import os
+import re
+import subprocess
+import shutil
+import time
+import urlparse
+
+from functest.core import testcase_base
+from functest.utils.constants import CONST
+import functest.utils.functest_logger as ft_logger
+import functest.utils.functest_utils as ft_utils
+import functest.utils.openstack_utils as openstack_utils
+
+
+logger = ft_logger.Logger(__name__).getLogger()
+
+
+class OnosBase(testcase_base.TestcaseBase):
+ onos_repo_path = CONST.dir_repo_onos
+ onos_sfc_image_name = CONST.onos_sfc_image_name
+ onos_sfc_image_path = os.path.join(CONST.dir_functest_data,
+ CONST.onos_sfc_image_file_name)
+ onos_sfc_path = os.path.join(CONST.dir_repo_functest,
+ CONST.dir_onos_sfc)
+
+ def __init__(self):
+ super(OnosBase, self).__init__()
+
+ def run(self):
+ self.start_time = time.time()
+ try:
+ self._run()
+ res = testcase_base.TestcaseBase.EX_OK
+ except Exception as e:
+ logger.error('Error with run: %s', e)
+ res = testcase_base.TestcaseBase.EX_RUN_ERROR
+
+ self.stop_time = time.time()
+ return res
+
+ def _run(self):
+ raise NotImplementedError('_run is not implemented')
+
+
+class Onos(OnosBase):
+ def __init__(self):
+ super(Onos, self).__init__()
+ self.case_name = 'onos'
+ self.log_path = os.path.join(self.onos_repo_path, 'TestON/logs')
+
+ def set_onos_ip(self):
+ if (CONST.INSTALLER_TYPE and
+ CONST.INSTALLER_TYPE.lower() == 'joid'):
+ sdn_controller_env = os.getenv('SDN_CONTROLLER')
+ OC1 = re.search(r"\d+\.\d+\.\d+\.\d+", sdn_controller_env).group()
+ else:
+ neutron_url = openstack_utils.get_endpoint(service_type='network')
+ OC1 = urlparse.urlparse(neutron_url).hostname
+ os.environ['OC1'] = OC1
+ logger.debug("ONOS IP is %s" % OC1)
+
+ def run_onos_script(self, testname):
+ cli_dir = os.path.join(self.onos_repo_path, 'TestON/bin/cli.py')
+ cmd = '{0} run {1}'.format(cli_dir, testname)
+ logger.debug("Run script: %s" % testname)
+ ft_utils.execute_command_raise(
+ cmd,
+ error_msg=('Error when running ONOS script: %s'
+ % (testname)))
+
+ def clean_existing_logs(self):
+ log_dir = [f for f in os.listdir(self.log_path)]
+ for log in log_dir:
+ try:
+ if os.path.isdir(log):
+ shutil.rmtree(log)
+ elif os.path.isfile(log):
+ os.remove(log)
+ except OSError as e:
+ logger.error('Error with deleting file %s: %s',
+ log, e.strerror)
+
+ def get_result(self):
+ cmd = 'grep -rnh Fail {0}'.format(self.log_path)
+ p = subprocess.Popen(cmd,
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+
+ for line in p.stdout:
+ logger.debug(line)
+ if re.search("\s+[1-9]+\s+", line):
+ logger.debug("Testcase Fails\n" + line)
+
+ cmd = "grep -rnh 'Execution Time' {0}".format(self.log_path)
+ result_buffer = os.popen(cmd).read()
+ time1 = result_buffer[114:128]
+ time2 = result_buffer[28:42]
+ cmd = "grep -rnh 'Success Percentage' {0}".format(
+ os.path.join(self.log_path, "FUNCvirNetNB_*"))
+ result_buffer = os.popen(cmd).read()
+ if result_buffer.find('100%') >= 0:
+ result1 = 'Success'
+ else:
+ result1 = 'Failed'
+ cmd = "grep -rnh 'Success Percentage' {0}".format(
+ os.path.join(self.log_path, "FUNCvirNetNBL3*"))
+ result_buffer = os.popen(cmd).read()
+ if result_buffer.find('100%') >= 0:
+ result2 = 'Success'
+ else:
+ result2 = 'Failed'
+ status1 = []
+ status2 = []
+ cmd = "grep -rnh 'h3' {0}".format(
+ os.path.join(self.log_path, "FUNCvirNetNB_*"))
+ result_buffer = os.popen(cmd).read()
+ pattern = re.compile("<h3>([^-]+) - ([^-]+) - (\S*)</h3>")
+ # res = pattern.search(result_buffer).groups()
+ res = pattern.findall(result_buffer)
+ i = 0
+ for index in range(len(res)):
+ status1.append({'Case name:': res[i][0] + res[i][1],
+ 'Case result': res[i][2]})
+ i = i + 1
+ cmd = "grep -rnh 'h3' {0}".format(
+ os.path.join(self.log_path, "FUNCvirNetNBL3*"))
+ result_buffer = os.popen(cmd).read()
+ pattern = re.compile("<h3>([^-]+) - ([^-]+) - (\S*)</h3>")
+ res = pattern.findall(result_buffer)
+ i = 0
+ for index in range(len(res)):
+ status2.append({'Case name:': res[i][0] + res[i][1],
+ 'Case result': res[i][2]})
+ i = i + 1
+ payload = {'FUNCvirNet': {'duration': time1,
+ 'result': result1,
+ 'status': status1},
+ 'FUNCvirNetL3': {'duration': time2,
+ 'result': result2,
+ 'status': status2}}
+ return payload
+
+ def parse_result(self):
+ result = self.get_result()
+ status = "FAIL"
+ try:
+ if (result['FUNCvirNet']['result'] == "Success" and
+ result['FUNCvirNetL3']['result'] == "Success"):
+ status = "PASS"
+ except:
+ logger.error("Unable to set ONOS criteria")
+
+ self.criteria = status
+ self.details = result
+
+ def _run(self):
+ self.clean_existing_logs()
+ self.set_onos_ip()
+ self.run_onos_script('FUNCvirNetNB')
+ self.run_onos_script('FUNCvirNetNBL3')
+ self.parse_result()
+
+
+class OnosSfc(OnosBase):
+ def __init__(self):
+ super(OnosSfc, self).__init__()
+ self.case_name = 'onos_sfc'
+
+ def get_ip(type):
+ url = openstack_utils.get_endpoint(service_type=type)
+ logger.debug('get_ip for %s: %s' % (type, url))
+ return urlparse.urlparse(url).hostname
+
+ def update_sfc_onos_file(self, before, after):
+ file_dir = os.path.join(self.onos_sfc_path, "sfc_onos.py")
+ cmd = "sed -i 's/{0}/{1}/g' {2}".format(before,
+ after,
+ file_dir)
+ ft_utils.execute_command_raise(
+ cmd,
+ error_msg=('Error with replacing %s with %s'
+ % (before, after)))
+
+ def create_image(self):
+ glance_client = openstack_utils.get_glance_client()
+ image_id = openstack_utils.create_glance_image(
+ glance_client,
+ self.onos_sfc_image_name,
+ self.onos_sfc_image_path)
+ if image_id is None:
+ raise Exception('Failed to create image')
+
+ logger.debug("Image '%s' with ID=%s is created successfully."
+ % (self.onos_sfc_image_name, image_id))
+
+ def set_sfc_conf(self):
+ self.update_sfc_onos_file("keystone_ip", self.get_ip("keystone"))
+ self.update_sfc_onos_file("neutron_ip", self.get_ip("neutron"))
+ self.update_sfc_onos_file("nova_ip", self.get_ip("nova"))
+ self.update_sfc_onos_file("glance_ip", self.get_ip("glance"))
+ self.update_sfc_onos_file("console", CONST.OS_PASSWORD)
+ neutron_client = openstack_utils.get_neutron_client()
+ ext_net = openstack_utils.get_external_net(neutron_client)
+ self.update_sfc_onos_file("admin_floating_net", ext_net)
+ logger.debug("SFC configuration is modified")
+
+ def sfc_test(self):
+ cmd = 'python {0}'.format(os.path.join(self.onos_sfc_path, 'sfc.py'))
+ ft_utils.execute_command_raise(cmd,
+ error_msg='Error with testing SFC')
+
+ def _run(self):
+ self.create_image()
+ self.set_sfc_conf()
+ self.sfc_test()
diff --git a/functest/opnfv_tests/sdn/onos/teston/onos.py b/functest/opnfv_tests/sdn/onos/teston/onos.py
deleted file mode 100755
index 2537e18d..00000000
--- a/functest/opnfv_tests/sdn/onos/teston/onos.py
+++ /dev/null
@@ -1,261 +0,0 @@
-"""
-Description: This test is to run onos Teston VTN scripts
-
-List of test cases:
-CASE1 - Northbound NBI test network/subnet/ports
-CASE2 - Ovsdb test&Default configuration&Vm go online
-
-lanqinglong@huawei.com
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-"""
-
-import datetime
-import os
-import re
-import time
-import urlparse
-
-import argparse
-from neutronclient.v2_0 import client as neutronclient
-
-import functest.utils.functest_constants as ft_constants
-import functest.utils.functest_logger as ft_logger
-import functest.utils.functest_utils as ft_utils
-import functest.utils.openstack_utils as openstack_utils
-
-
-parser = argparse.ArgumentParser()
-parser.add_argument("-t", "--testcase", help="Testcase name")
-args = parser.parse_args()
-
-
-""" logging configuration """
-logger = ft_logger.Logger("onos").getLogger()
-
-# onos parameters
-ONOSCI_PATH = ft_constants.REPOS_DIR + "/"
-starttime = datetime.datetime.now()
-
-INSTALLER_TYPE = ft_constants.CI_INSTALLER_TYPE
-ONOS_SFC_IMAGE_NAME = ft_constants.ONOS_SFC_IMAGE_NAME
-ONOS_SFC_IMAGE_PATH = os.path.join(ft_constants.FUNCTEST_DATA_DIR,
- ft_constants.ONOS_SFC_IMAGE_FILENAME)
-ONOS_SFC_PATH = os.path.join(ft_constants.FUNCTEST_REPO_DIR,
- ft_constants.ONOS_SFC_RELATIVE_PATH)
-
-
-def RunScript(testname):
- """
- Run ONOS Test Script
- Parameters:
- testname: ONOS Testcase Name
- """
- runtest = ONOSCI_PATH + "onos/TestON/bin/cli.py run " + testname
- logger.debug("Run script " + testname)
- os.system(runtest)
-
-
-def DownloadCodes(url="https://github.com/wuwenbin2/OnosSystemTest.git"):
- """
- Download Onos Teston codes
- Parameters:
- url: github url
- """
- downloadcode = "git clone " + url + " " + ONOSCI_PATH + "OnosSystemTest"
- logger.debug("Download Onos Teston codes " + url)
- os.system(downloadcode)
-
-
-def GetResult():
- LOGPATH = ONOSCI_PATH + "onos/TestON/logs"
- cmd = "grep -rnh " + "Fail" + " " + LOGPATH
- Resultbuffer = os.popen(cmd).read()
- # duration = datetime.datetime.now() - starttime
- time.sleep(2)
-
- if re.search("\s+[1-9]+\s+", Resultbuffer):
- logger.debug("Testcase Fails\n" + Resultbuffer)
- # Result = "Failed"
- else:
- logger.debug("Testcases Success")
- # Result = "Success"
- # payload={'timestart': str(starttime),
- # 'duration': str(duration),
- # 'status': Result}
- cmd = "grep -rnh 'Execution Time' " + LOGPATH
- Resultbuffer = os.popen(cmd).read()
- time1 = Resultbuffer[114:128]
- time2 = Resultbuffer[28:42]
- cmd = "grep -rnh 'Success Percentage' " + LOGPATH + "/FUNCvirNetNB_*"
- Resultbuffer = os.popen(cmd).read()
- if Resultbuffer.find('100%') >= 0:
- result1 = 'Success'
- else:
- result1 = 'Failed'
- cmd = "grep -rnh 'Success Percentage' " + LOGPATH + "/FUNCvirNetNBL3*"
- Resultbuffer = os.popen(cmd).read()
- if Resultbuffer.find('100%') >= 0:
- result2 = 'Success'
- else:
- result2 = 'Failed'
- status1 = []
- status2 = []
- cmd = "grep -rnh 'h3' " + LOGPATH + "/FUNCvirNetNB_*"
- Resultbuffer = os.popen(cmd).read()
- pattern = re.compile("<h3>([^-]+) - ([^-]+) - (\S*)</h3>")
- # res = pattern.search(Resultbuffer).groups()
- res = pattern.findall(Resultbuffer)
- i = 0
- for index in range(len(res)):
- status1.append({'Case name:': res[i][0] + res[i][1],
- 'Case result': res[i][2]})
- i = i + 1
- cmd = "grep -rnh 'h3' " + LOGPATH + "/FUNCvirNetNBL3*"
- Resultbuffer = os.popen(cmd).read()
- pattern = re.compile("<h3>([^-]+) - ([^-]+) - (\S*)</h3>")
- # res = pattern.search(Resultbuffer).groups()
- res = pattern.findall(Resultbuffer)
- i = 0
- for index in range(len(res)):
- status2.append({'Case name:': res[i][0] + res[i][1],
- 'Case result': res[i][2]})
- i = i + 1
- payload = {'timestart': str(starttime),
- 'FUNCvirNet': {'duration': time1,
- 'result': result1,
- 'status': status1},
- 'FUNCvirNetL3': {'duration': time2,
- 'result': result2,
- 'status': status2}}
- return payload
-
-
-def SetOnosIp():
- # cmd = "openstack catalog show network | grep publicURL"
- neutron_url = openstack_utils.get_endpoint(service_type='network')
- OC1 = urlparse.urlparse(neutron_url).hostname
- os.environ['OC1'] = OC1
- time.sleep(2)
- logger.debug("ONOS IP is " + OC1)
-
-
-def SetOnosIpForJoid():
- cmd = "env | grep SDN_CONTROLLER"
- cmd_output = os.popen(cmd).read()
- OC1 = re.search(r"\d+\.\d+\.\d+\.\d+", cmd_output).group()
- os.environ['OC1'] = OC1
- time.sleep(2)
- logger.debug("ONOS IP is " + OC1)
-
-
-def CleanOnosTest():
- TESTONPATH = ONOSCI_PATH + "onos/"
- cmd = "rm -rf " + TESTONPATH
- os.system(cmd)
- time.sleep(2)
- logger.debug("Clean ONOS Teston")
-
-
-def CreateImage():
- glance_client = openstack_utils.get_glance_client()
- image_id = openstack_utils.create_glance_image(glance_client,
- ONOS_SFC_IMAGE_NAME,
- ONOS_SFC_IMAGE_PATH)
- EXIT_CODE = -1
- if not image_id:
- logger.error("Failed to create a Glance image...")
- return(EXIT_CODE)
- logger.debug("Image '%s' with ID=%s created successfully."
- % (ONOS_SFC_IMAGE_NAME, image_id))
-
-
-def SfcTest():
- cmd = "python " + ONOS_SFC_PATH + "/sfc.py"
- logger.debug("Run sfc tests")
- os.system(cmd)
-
-
-def GetIp(type):
- # cmd = "openstack catalog show " + type + " | grep publicURL"
- url = openstack_utils.get_endpoint(service_type=type)
- return urlparse.urlparse(url).hostname
-
-
-def Replace(before, after):
- file = "/sfc_onos.py"
- cmd = "sed -i 's/" + before + "/" + after + "/g' " + ONOS_SFC_PATH + file
- os.system(cmd)
-
-
-def SetSfcConf():
- Replace("keystone_ip", GetIp("keystone"))
- Replace("neutron_ip", GetIp("neutron"))
- Replace("nova_ip", GetIp("nova"))
- Replace("glance_ip", GetIp("glance"))
- pwd = ft_constants.OS_PASSWORD
- Replace("console", pwd)
- creds_neutron = openstack_utils.get_credentials()
- neutron_client = neutronclient.Client(**creds_neutron)
- ext_net = openstack_utils.get_external_net(neutron_client)
- Replace("admin_floating_net", ext_net)
- logger.info("Modify configuration for SFC")
-
-
-def OnosTest():
- start_time = time.time()
- stop_time = start_time
- if INSTALLER_TYPE == "joid":
- logger.debug("Installer is Joid")
- SetOnosIpForJoid()
- else:
- SetOnosIp()
- RunScript("FUNCvirNetNB")
- RunScript("FUNCvirNetNBL3")
- try:
- logger.debug("Push ONOS results into DB")
- # TODO check path result for the file
- result = GetResult()
- stop_time = time.time()
-
- # ONOS success criteria = all tests OK
- # i.e. FUNCvirNet & FUNCvirNetL3
- status = "FAIL"
- try:
- if (result['FUNCvirNet']['result'] == "Success" and
- result['FUNCvirNetL3']['result'] == "Success"):
- status = "PASS"
- except:
- logger.error("Unable to set ONOS criteria")
-
- ft_utils.push_results_to_db("functest",
- "onos",
- start_time,
- stop_time,
- status,
- result)
-
- except:
- logger.error("Error pushing results into Database")
-
- if status == "FAIL":
- EXIT_CODE = -1
- exit(EXIT_CODE)
-
-
-def main():
-
- if args.testcase == "sfc":
- CreateImage()
- SetSfcConf()
- SfcTest()
- else:
- OnosTest()
-
-
-if __name__ == '__main__':
- main()
diff --git a/functest/tests/unit/utils/test_openstack_utils.py b/functest/tests/unit/utils/test_openstack_utils.py
index 447271fc..ef3764cc 100644
--- a/functest/tests/unit/utils/test_openstack_utils.py
+++ b/functest/tests/unit/utils/test_openstack_utils.py
@@ -104,7 +104,6 @@ class OSUtilsTesting(unittest.TestCase):
'servers.create.return_value': self.instance,
'flavors.list.return_value': [self.flavor],
'flavors.find.return_value': self.flavor,
- 'flavors.list.return_value': [self.flavor],
'servers.add_floating_ip.return_value': mock.Mock(),
'servers.force_delete.return_value': mock.Mock(),
'aggregates.list.return_value': [self.aggregate],
@@ -162,6 +161,15 @@ class OSUtilsTesting(unittest.TestCase):
}
self.cinder_client.configure_mock(**attrs)
+ self.resource = mock.Mock()
+ attrs = {'id': 'resource_test_id',
+ 'name': 'resource_test_name'
+ }
+
+ self.heat_client = mock.Mock()
+ attrs = {'resources.get.return_value': self.resource}
+ self.heat_client.configure_mock(**attrs)
+
mock_obj = mock.Mock()
attrs = {'id': 'tenant_id',
'name': 'test_tenant'}
@@ -543,6 +551,36 @@ class OSUtilsTesting(unittest.TestCase):
mock_glan_client.assert_called_once_with('3',
session=mock_session_obj)
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value=None)
+ def test_get_heat_client_version_missing_env(self, mock_os_getenv):
+ self.assertEqual(openstack_utils.get_heat_client_version(),
+ openstack_utils.DEFAULT_HEAT_API_VERSION)
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ @mock.patch('functest.utils.openstack_utils.os.getenv', return_value='1')
+ def test_get_heat_client_version_default(self, mock_os_getenv,
+ mock_logger_info):
+ self.assertEqual(openstack_utils.get_heat_client_version(), '1')
+ mock_logger_info.assert_called_once_with(
+ "OS_ORCHESTRATION_API_VERSION is set in env as '%s'", '1')
+
+ def test_get_heat_client(self):
+ mock_heat_obj = mock.Mock()
+ mock_session_obj = mock.Mock()
+ with mock.patch('functest.utils.openstack_utils'
+ '.get_heat_client_version', return_value='1'), \
+ mock.patch('functest.utils.openstack_utils'
+ '.heatclient.Client',
+ return_value=mock_heat_obj) \
+ as mock_heat_client, \
+ mock.patch('functest.utils.openstack_utils.get_session',
+ return_value=mock_session_obj):
+ self.assertEqual(openstack_utils.get_heat_client(),
+ mock_heat_obj)
+ mock_heat_client.assert_called_once_with('1',
+ session=mock_session_obj)
+
def test_get_instances_default(self):
self.assertEqual(openstack_utils.get_instances(self.nova_client),
[self.instance])
@@ -1700,6 +1738,24 @@ class OSUtilsTesting(unittest.TestCase):
'user_id'))
self.assertTrue(mock_logger_error.called)
+ def test_get_resource_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=True):
+ self.assertEqual(openstack_utils.
+ get_resource(self.heat_client,
+ 'stack_id',
+ 'resource'),
+ self.resource)
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_resource_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_resource(Exception,
+ 'stack_id',
+ 'resource'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
if __name__ == "__main__":
unittest.main(verbosity=2)
diff --git a/functest/utils/config.py b/functest/utils/config.py
index 84166c1d..b5b84501 100644..100755
--- a/functest/utils/config.py
+++ b/functest/utils/config.py
@@ -2,26 +2,25 @@ import os
import yaml
+import env
+
class Config(object):
def __init__(self):
- if 'CONFIG_FUNCTEST_YAML' not in os.environ:
- raise Exception('CONFIG_FUNCTEST_YAML not configed')
- self.config_functest = os.environ['CONFIG_FUNCTEST_YAML']
try:
- with open(self.config_functest) as f:
+ with open(env.ENV.CONFIG_FUNCTEST_YAML) as f:
self.functest_yaml = yaml.safe_load(f)
self._parse(None, self.functest_yaml)
- except:
- raise Exception('Parse {} failed'.format(self.config_functest))
+ except Exception as error:
+ raise Exception('Parse config failed: {}'.format(str(error)))
self._set_others()
def _parse(self, attr_now, left_parametes):
for param_n, param_v in left_parametes.iteritems():
attr_further = self._get_attr_further(attr_now, param_n)
- if not isinstance(param_v, dict):
+ if attr_further:
self.__setattr__(attr_further, param_v)
- else:
+ if isinstance(param_v, dict):
self._parse(attr_further, param_v)
def _get_attr_further(self, attr_now, next):
@@ -33,3 +32,8 @@ class Config(object):
CONF = Config()
+
+if __name__ == "__main__":
+ print CONF.vnf_cloudify_ims
+ print CONF.vnf_cloudify_ims_tenant_images
+ print CONF.vnf_cloudify_ims_tenant_images_centos_7
diff --git a/functest/utils/functest_constants.py b/functest/utils/functest_constants.py
index 0a9a03b1..9fae9a9c 100644
--- a/functest/utils/functest_constants.py
+++ b/functest/utils/functest_constants.py
@@ -94,15 +94,6 @@ SDNVPN_REPO_DIR = get_value('general.dir.repo_sdnvpn',
'SDNVPN_REPO_DIR')
SFC_REPO_DIR = get_value('general.dir.repo_sfc',
'SFC_REPO_DIR')
-
-ONOS_SFC_IMAGE_NAME = get_value('onos_sfc.image_name',
- 'ONOS_SFC_IMAGE_NAME')
-ONOS_SFC_IMAGE_FILENAME = get_value('onos_sfc.image_file_name',
- 'ONOS_SFC_IMAGE_FILENAME')
-ONOS_SFC_RELATIVE_PATH = get_value('general.dir.dir_onos_sfc',
- 'ONOS_SFC_RELATIVE_PATH')
-ONOS_SFC_IMAGE_BASE_URL = get_value('onos_sfc.image_base_url',
- 'ONOS_SFC_IMAGE_BASE_URL')
RALLY_RELATIVE_PATH = get_value('general.dir.rally',
'RALLY_RELATIVE_PATH')
RALLY_PRIVATE_NET_NAME = get_value('rally.network_name',
diff --git a/functest/utils/openstack_utils.py b/functest/utils/openstack_utils.py
index 3093cb55..e33af63b 100755
--- a/functest/utils/openstack_utils.py
+++ b/functest/utils/openstack_utils.py
@@ -18,6 +18,7 @@ from keystoneauth1 import loading
from keystoneauth1 import session
from cinderclient import client as cinderclient
from glanceclient import client as glanceclient
+from heatclient import client as heatclient
from novaclient import client as novaclient
from keystoneclient import client as keystoneclient
from neutronclient.neutron import client as neutronclient
@@ -28,6 +29,7 @@ import functest.utils.functest_utils as ft_utils
logger = ft_logger.Logger("openstack_utils").getLogger()
DEFAULT_API_VERSION = '2'
+DEFAULT_HEAT_API_VERSION = '1'
# *********************************************
@@ -241,6 +243,20 @@ def get_glance_client(other_creds={}):
return glanceclient.Client(get_glance_client_version(), session=sess)
+def get_heat_client_version():
+ api_version = os.getenv('OS_ORCHESTRATION_API_VERSION')
+ if api_version is not None:
+ logger.info("OS_ORCHESTRATION_API_VERSION is set in env as '%s'",
+ api_version)
+ return api_version
+ return DEFAULT_HEAT_API_VERSION
+
+
+def get_heat_client(other_creds={}):
+ sess = get_session(other_creds)
+ return heatclient.Client(get_heat_client_version(), session=sess)
+
+
# *********************************************
# NOVA
# *********************************************
@@ -985,36 +1001,43 @@ def create_security_group(neutron_client, sg_name, sg_description):
def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
port_range_min=None, port_range_max=None):
- if port_range_min is None and port_range_max is None:
- json_body = {'security_group_rule': {'direction': direction,
- 'security_group_id': sg_id,
- 'protocol': protocol}}
- elif port_range_min is not None and port_range_max is not None:
- json_body = {'security_group_rule': {'direction': direction,
- 'security_group_id': sg_id,
- 'port_range_min': port_range_min,
- 'port_range_max': port_range_max,
- 'protocol': protocol}}
+ # We create a security group in 2 steps
+ # 1 - we check the format and set the json body accordingly
+ # 2 - we call neturon client to create the security group
+
+ # Format check
+ json_body = {'security_group_rule': {'direction': direction,
+ 'security_group_id': sg_id,
+ 'protocol': protocol}}
+ # parameters may be
+ # - both None => we do nothing
+ # - both Not None => we add them to the json description
+ # but one cannot be None is the other is not None
+ if (port_range_min is not None and port_range_max is not None):
+ # add port_range in json description
+ json_body['security_group_rule']['port_range_min'] = port_range_min
+ json_body['security_group_rule']['port_range_max'] = port_range_max
+ logger.debug("Security_group format set (port range included)")
else:
- logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
- "'%s', '%s', '%s', '%s')]:" % (neutron_client,
- sg_id, direction,
- port_range_min,
- port_range_max,
- protocol),
- " Invalid values for port_range_min, port_range_max")
- return False
+ # either both port range are set to None => do nothing
+ # or one is set but not the other => log it and return False
+ if port_range_min is None and port_range_max is None:
+ logger.debug("Security_group format set (no port range mentioned)")
+ else:
+ logger.error("Bad security group format."
+ "One of the port range is not properly set:"
+ "range min: {},"
+ "range max: {}".format(port_range_min,
+ port_range_max))
+ return False
+
+ # Create security group using neutron client
try:
neutron_client.create_security_group_rule(json_body)
return True
- except Exception, e:
- logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
- "'%s', '%s', '%s', '%s')]: %s" % (neutron_client,
- sg_id,
- direction,
- port_range_min,
- port_range_max,
- protocol, e))
+ except:
+ logger.exception("Impossible to create_security_group_rule,"
+ "security group rule probably already exists")
return False
@@ -1383,3 +1406,15 @@ def delete_user(keystone_client, user_id):
logger.error("Error [delete_user(keystone_client, '%s')]: %s"
% (user_id, e))
return False
+
+
+# *********************************************
+# HEAT
+# *********************************************
+def get_resource(heat_client, stack_id, resource):
+ try:
+ resources = heat_client.resources.get(stack_id, resource)
+ return resources
+ except Exception, e:
+ logger.error("Error [get_resource]: %s" % e)
+ return None