summaryrefslogtreecommitdiffstats
path: root/functest
diff options
context:
space:
mode:
Diffstat (limited to 'functest')
-rw-r--r--functest/ci/config_aarch64_patch.yaml20
-rwxr-xr-xfunctest/ci/config_functest.yaml7
-rwxr-xr-xfunctest/ci/config_patch.yaml6
-rwxr-xr-xfunctest/ci/prepare_env.py107
-rw-r--r--functest/ci/rally_aarch64_patch.conf5
-rwxr-xr-xfunctest/ci/testcases.yaml45
-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/vnf/ims/cloudify_ims.py13
-rwxr-xr-xfunctest/opnfv_tests/vnf/router/__init__.py0
-rwxr-xr-xfunctest/opnfv_tests/vnf/router/vyos_vrouter.py33
-rw-r--r--functest/tests/unit/opnfv_tests/vnf/__init__.py0
-rw-r--r--functest/tests/unit/opnfv_tests/vnf/ims/__init__.py0
-rw-r--r--functest/tests/unit/opnfv_tests/vnf/ims/test_clearwater.py54
-rw-r--r--functest/tests/unit/opnfv_tests/vnf/ims/test_cloudify_ims.py542
-rw-r--r--functest/tests/unit/opnfv_tests/vnf/ims/test_orchestrator_cloudify.py122
-rw-r--r--functest/tests/unit/utils/test_openstack_utils.py58
-rwxr-xr-x[-rw-r--r--]functest/utils/config.py20
-rwxr-xr-xfunctest/utils/openstack_utils.py87
22 files changed, 1043 insertions, 109 deletions
diff --git a/functest/ci/config_aarch64_patch.yaml b/functest/ci/config_aarch64_patch.yaml
new file mode 100644
index 000000000..9a345e3f7
--- /dev/null
+++ b/functest/ci/config_aarch64_patch.yaml
@@ -0,0 +1,20 @@
+os:
+ general:
+ openstack:
+ image_name: TestVM
+ image_file_name: cirros-d161201-aarch64-disk.img
+ image_password: gocubsgo
+
+ snaps_simple_healthcheck:
+ disk_image: /home/opnfv/functest/data/cirros-d161201-aarch64-disk.img
+ kernel_image: /home/opnfv/functest/data/cirros-d161201-aarch64-kernel
+ ramdisk_image: /home/opnfv/functest/data/cirros-d161201-aarch64-initramfs
+ extra_properties:
+ os_command_line: root=/dev/vdb1 rw rootwait console=tty0 console=ttyS0 console=ttyAMA0
+ hw_video_model: vga
+
+ vping:
+ image_name: TestVM
+
+ doctor:
+ image_name: TestVM
diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml
index a3eebab7b..402e29999 100755
--- a/functest/ci/config_functest.yaml
+++ b/functest/ci/config_functest.yaml
@@ -29,6 +29,7 @@ general:
repo_domino: /home/opnfv/repos/domino
repo_snaps: /home/opnfv/repos/snaps
repo_securityscan: /home/opnfv/repos/securityscanning
+ repo_vrouter: /home/opnfv/repos/vrouter
functest: /home/opnfv/functest
functest_test: /home/opnfv/repos/functest/functest/opnfv_tests
results: /home/opnfv/functest/results
@@ -42,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:)
@@ -66,7 +67,7 @@ general:
testcases_yaml: /home/opnfv/repos/functest/functest/ci/testcases.yaml
healthcheck:
- disk_image: /home/opnfv/functest/data/cirros-0.3.4-x86_64-disk.img
+ disk_image: /home/opnfv/functest/data/cirros-0.3.5-x86_64-disk.img
disk_format: qcow2
wait_time: 60
diff --git a/functest/ci/config_patch.yaml b/functest/ci/config_patch.yaml
index 46064a07f..d984a3f47 100755
--- a/functest/ci/config_patch.yaml
+++ b/functest/ci/config_patch.yaml
@@ -1,12 +1,12 @@
lxd:
general:
openstack:
- image_name: Cirros-0.3.4
- image_file_name: cirros-0.3.4-x86_64-lxc.tar.gz
+ image_name: Cirros-0.3.5
+ image_file_name: cirros-0.3.5-x86_64-lxc.tar.gz
image_disk_format: raw
healthcheck:
- disk_image: /home/opnfv/functest/data/cirros-0.3.4-x86_64-lxc.tar.gz
+ disk_image: /home/opnfv/functest/data/cirros-0.3.5-x86_64-lxc.tar.gz
disk_format: raw
fdio:
general:
diff --git a/functest/ci/prepare_env.py b/functest/ci/prepare_env.py
index 5a9f99cb6..724ea14df 100755
--- a/functest/ci/prepare_env.py
+++ b/functest/ci/prepare_env.py
@@ -12,6 +12,7 @@ import os
import re
import subprocess
import sys
+import fileinput
import yaml
@@ -27,14 +28,19 @@ actions = ['start', 'check']
""" logging configuration """
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(
CONFIG_FUNCTEST_PATH), "config_patch.yaml")
-
-with open(CONFIG_PATCH_PATH) as f:
- functest_patch_yaml = yaml.safe_load(f)
+CONFIG_AARCH64_PATCH_PATH = os.path.join(os.path.dirname(
+ CONFIG_FUNCTEST_PATH), "config_aarch64_patch.yaml")
+RALLY_CONF_PATH = os.path.join("/etc/rally/rally.conf")
+RALLY_AARCH64_PATCH_PATH = os.path.join(os.path.dirname(
+ CONFIG_FUNCTEST_PATH), "rally_aarch64_patch.conf")
class PrepareEnvParser(object):
@@ -102,6 +108,38 @@ def check_env_variables():
logger.info(" IS_CI_RUN=%s" % CONST.IS_CI_RUN)
+def get_deployment_handler():
+ global handler
+ global pod_arch
+
+ installer_params_yaml = os.path.join(CONST.dir_repo_functest,
+ 'functest/ci/installer_params.yaml')
+ if (CONST.INSTALLER_IP and CONST.INSTALLER_TYPE and
+ CONST.INSTALLER_TYPE in opnfv_constants.INSTALLERS):
+ try:
+ 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():
print_separator()
logger.info("Creating needed directories...")
@@ -163,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':
@@ -178,11 +215,22 @@ def source_rc_file():
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)
+
updated = False
- for key in functest_patch_yaml:
+ for key in patch_file:
if key in CONST.DEPLOY_SCENARIO:
new_functest_yaml = dict(ft_utils.merge_dicts(
- ft_utils.get_functest_yaml(), functest_patch_yaml[key]))
+ ft_utils.get_functest_yaml(), patch_file[key]))
updated = True
if updated:
@@ -210,6 +258,17 @@ def verify_deployment():
def install_rally():
print_separator()
+
+ 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()
+
+ for line in fileinput.input(RALLY_CONF_PATH, inplace=1):
+ print line,
+ if "cirros|testvm" in line:
+ print rally_patch_conf
+
logger.info("Creating Rally environment...")
cmd = "rally deployment destroy opnfv-rally"
@@ -284,34 +343,9 @@ def check_environment():
def print_deployment_info():
- installer_params_yaml = os.path.join(CONST.dir_repo_functest,
- 'functest/ci/installer_params.yaml')
- if (CONST.INSTALLER_IP and CONST.INSTALLER_TYPE and
- CONST.INSTALLER_TYPE in opnfv_constants.INSTALLERS):
- try:
- 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:
- logger.info('\n\nDeployment information:\n%s' %
- handler.get_deployment_info())
- except Exception as e:
- logger.debug("Cannot get deployment information. %s" % e)
+ if handler:
+ logger.info('\n\nDeployment information:\n%s' %
+ handler.get_deployment_info())
def main(**kwargs):
@@ -322,6 +356,7 @@ def main(**kwargs):
elif kwargs['action'] == "start":
logger.info("######### Preparing Functest environment #########\n")
check_env_variables()
+ get_deployment_handler()
create_directories()
source_rc_file()
patch_config_file()
diff --git a/functest/ci/rally_aarch64_patch.conf b/functest/ci/rally_aarch64_patch.conf
new file mode 100644
index 000000000..a49588bf8
--- /dev/null
+++ b/functest/ci/rally_aarch64_patch.conf
@@ -0,0 +1,5 @@
+img_name_regex = ^TestVM$
+img_url = http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-disk.img
+flavor_ref_ram = 128
+flavor_ref_alt_ram = 256
+heat_instance_type_ram = 128
diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml
index 1e5ba758c..77cd1ae64 100755
--- a/functest/ci/testcases.yaml
+++ b/functest/ci/testcases.yaml
@@ -74,7 +74,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'
@@ -118,7 +118,7 @@ tiers:
Rally suite in smoke mode.
dependencies:
installer: ''
- scenario: '^((?!bgpvpn).)*$'
+ scenario: ''
run:
module: 'functest.opnfv_tests.openstack.rally.rally'
class: 'RallySanity'
@@ -318,6 +318,18 @@ tiers:
module: 'functest.opnfv_tests.vnf.rnc.parser'
class: 'Parser'
-
+ name: domino
+ criteria: 'status == "PASS"'
+ blocking: false
+ description: >-
+ Test suite from Domino project.
+ dependencies:
+ installer: ''
+ scenario: ''
+ run:
+ module: 'functest.opnfv_tests.features.domino'
+ class: 'Domino'
+ -
name: orchestra
criteria: 'ret == 0'
blocking: false
@@ -390,6 +402,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%'
@@ -475,3 +503,16 @@ tiers:
run:
module: 'functest.opnfv_tests.vnf.ims.opera_ims'
class: 'ImsVnf'
+
+ -
+ name: vyos_vrouter
+ criteria: 'status == "PASS"'
+ blocking: false
+ description: >-
+ This test case is vRouter testing.
+ dependencies:
+ installer: 'fuel'
+ scenario: 'nosdn-nofeature'
+ run:
+ module: 'functest.opnfv_tests.vnf.router.vyos_vrouter'
+ class: 'VrouterVnf'
diff --git a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
index 909f45d21..ed5e61fe0 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
+++ b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_ports.yaml.template
@@ -7,7 +7,7 @@ parameters:
default: public
image:
type: string
- default: cirros-0.3.4-x86_64-uec
+ default: cirros-0.3.5-x86_64-uec
flavor:
type: string
default: m1.tiny
diff --git a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
index 826ca9dae..116b5bb6c 100644
--- a/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
+++ b/functest/opnfv_tests/openstack/rally/scenario/templates/server_with_volume.yaml.template
@@ -4,7 +4,7 @@ parameters:
# set all correct defaults for parameters before launch test
image:
type: string
- default: cirros-0.3.4-x86_64-uec
+ default: cirros-0.3.5-x86_64-uec
flavor:
type: string
default: m1.tiny
diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
index 0a4256ce6..fcdfe225b 100644
--- a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
+++ b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
@@ -1,22 +1,3 @@
--
- scenarios:
- - os-odl_l2-bgpvpn-ha
- - os-odl_l2-bgpvpn-noha
- installers:
- - fuel
- - apex
- tests:
- - tempest.api.compute.servers.test_create_server.ServersTestJSON.test_list_servers
- - tempest.api.compute.servers.test_create_server.ServersTestJSON.test_verify_server_details
- - tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers
- - tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_server_details
- - tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_hard
- - tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_create_list_show_update_delete_floating_ip
- - tempest.api.network.test_floating_ips.FloatingIPTestJSON.test_create_floating_ip_specifying_a_fixed_ip_address
- - tempest.scenario.test_network_basic_ops.TestNetworkBasicOps.test_network_basic_ops
- - tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops
- - tempest.scenario.test_volume_boot_pattern.TestVolumeBootPattern.test_volume_boot_pattern
- - tempest.scenario.test_volume_boot_pattern.TestVolumeBootPatternV2.test_volume_boot_pattern
-
scenarios:
diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt b/functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt
new file mode 100644
index 000000000..ac4e37289
--- /dev/null
+++ b/functest/opnfv_tests/openstack/tempest/custom_tests/test_list.txt
@@ -0,0 +1,4 @@
+# This is an empty file to be filled up with the desired tempest test cases
+# Examples:
+#tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops
+#tempest.scenario.test_network_basic_ops.TestNetworkBasicOps.test_network_basic_ops \ No newline at end of file
diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py
index 37b5c0ee7..4c96500db 100644
--- a/functest/opnfv_tests/openstack/tempest/tempest.py
+++ b/functest/opnfv_tests/openstack/tempest/tempest.py
@@ -324,11 +324,11 @@ class TempestMultisite(TempestCommon):
class TempestCustom(TempestCommon):
- def __init__(self, mode, option):
+ def __init__(self):
TempestCommon.__init__(self)
self.case_name = "tempest_custom"
- self.MODE = mode
- self.OPTION = option
+ self.MODE = "custom"
+ self.OPTION = "--concurrency 1"
class TempestDefcore(TempestCommon):
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
index 584d780a5..c2c251ad2 100644
--- a/functest/opnfv_tests/vnf/ims/cloudify_ims.py
+++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
@@ -195,8 +195,9 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
return {'status': 'PASS', 'result': ''}
def deploy_vnf(self):
- cw = Clearwater(self.vnf.inputs, self.orchestrator.object, self.logger)
- self.vnf.object = cw
+ cw = Clearwater(self.vnf['inputs'], self.orchestrator['object'],
+ self.logger)
+ self.vnf['object'] = cw
self.logger.info("Collect flavor id for all clearwater vm")
flavor_exist, flavor_id = os_utils.get_or_create_flavor(
@@ -215,7 +216,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
cw.set_flavor_id(flavor_id)
# VMs image
- if 'os_image' in self.vnf.requirements.keys():
+ if 'os_image' in self.vnf['requirements'].keys():
image_id = os_utils.get_image_id(
self.glance_client, self.vnf['requirements']['os_image'])
if image_id == '':
@@ -256,7 +257,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
api_url = "http://" + mgr_ip + "/api/v2"
dep_outputs = requests.get(api_url + "/deployments/" +
- self.vnf.deployment_name + "/outputs")
+ self.vnf['deployment_name'] + "/outputs")
dns_ip = dep_outputs.json()['outputs']['dns_ip']
ellis_ip = dep_outputs.json()['outputs']['ellis_ip']
@@ -340,8 +341,8 @@ class ImsVnf(vnf_base.VnfOnBoardingBase):
return {'status': 'FAIL', 'result': ''}
def clean(self):
- self.vnf.object.undeploy_vnf()
- self.orchestrator.object.undeploy_manager()
+ self.vnf['object'].undeploy_vnf()
+ self.orchestrator['object'].undeploy_manager()
super(ImsVnf, self).clean()
def main(self, **kwargs):
diff --git a/functest/opnfv_tests/vnf/router/__init__.py b/functest/opnfv_tests/vnf/router/__init__.py
new file mode 100755
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/__init__.py
diff --git a/functest/opnfv_tests/vnf/router/vyos_vrouter.py b/functest/opnfv_tests/vnf/router/vyos_vrouter.py
new file mode 100755
index 000000000..94a3ecfd8
--- /dev/null
+++ b/functest/opnfv_tests/vnf/router/vyos_vrouter.py
@@ -0,0 +1,33 @@
+#!/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_base as base
+import json
+import os
+
+RESULT_DETAILS_FILE = "test_result.json"
+
+
+class VrouterVnf(base.FeatureBase):
+ def __init__(self):
+ super(VrouterVnf, self).__init__(project='vRouter',
+ case='vyos_vrouter',
+ repo='dir_repo_vrouter')
+ 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.criteria == 'PASS':
+ self.set_result_details()
+ super(VrouterVnf, self).log_results()
diff --git a/functest/tests/unit/opnfv_tests/vnf/__init__.py b/functest/tests/unit/opnfv_tests/vnf/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/tests/unit/opnfv_tests/vnf/__init__.py
diff --git a/functest/tests/unit/opnfv_tests/vnf/ims/__init__.py b/functest/tests/unit/opnfv_tests/vnf/ims/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/tests/unit/opnfv_tests/vnf/ims/__init__.py
diff --git a/functest/tests/unit/opnfv_tests/vnf/ims/test_clearwater.py b/functest/tests/unit/opnfv_tests/vnf/ims/test_clearwater.py
new file mode 100644
index 000000000..527f12e59
--- /dev/null
+++ b/functest/tests/unit/opnfv_tests/vnf/ims/test_clearwater.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import logging
+import unittest
+
+import mock
+
+from functest.opnfv_tests.vnf.ims import clearwater
+from functest.opnfv_tests.vnf.ims import orchestrator_cloudify
+
+
+class ClearwaterTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.clearwater = clearwater.Clearwater()
+ self.orchestrator = orchestrator_cloudify.Orchestrator('test_dir')
+ self.clearwater.orchestrator = self.orchestrator
+ self.clearwater.dep_name = 'test_dep_name'
+ self.bp = {'file_name': 'test_file',
+ 'destination_folder': 'test_folder',
+ 'url': 'test_url',
+ 'branch': 'test_branch'}
+
+ def test_deploy_vnf_blueprint_download_failed(self):
+ with mock.patch.object(self.clearwater.orchestrator,
+ 'download_upload_and_deploy_blueprint',
+ return_value='error'):
+ self.assertEqual(self.clearwater.deploy_vnf(self.bp),
+ 'error')
+
+ def test_deploy_vnf_blueprint_download_passed(self):
+ with mock.patch.object(self.clearwater.orchestrator,
+ 'download_upload_and_deploy_blueprint',
+ return_value=''):
+ self.clearwater.deploy_vnf(self.bp),
+ self.assertEqual(self.clearwater.deploy, True)
+
+ def test_undeploy_vnf_deployment_passed(self):
+ with mock.patch.object(self.clearwater.orchestrator,
+ 'undeploy_deployment'):
+ self.clearwater.deploy = True
+ self.clearwater.undeploy_vnf(),
+ self.assertEqual(self.clearwater.deploy, False)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/opnfv_tests/vnf/ims/test_cloudify_ims.py b/functest/tests/unit/opnfv_tests/vnf/ims/test_cloudify_ims.py
new file mode 100644
index 000000000..e25816f01
--- /dev/null
+++ b/functest/tests/unit/opnfv_tests/vnf/ims/test_cloudify_ims.py
@@ -0,0 +1,542 @@
+#!/usr/bin/env python
+
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import logging
+import unittest
+
+import mock
+
+from functest.opnfv_tests.vnf.ims import cloudify_ims
+
+
+class ImsVnfTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os.makedirs'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'get_config', return_value='config_value'):
+ self.ims_vnf = cloudify_ims.ImsVnf()
+ self.neutron_client = mock.Mock()
+ self.glance_client = mock.Mock()
+ self.keystone_client = mock.Mock()
+ self.nova_client = mock.Mock()
+ self.orchestrator = {'requirements': {'ram_min': 2,
+ 'os_image': 'test_os_image'},
+ 'blueprint': {'url': 'test_url',
+ 'branch': 'test_branch'},
+ 'inputs': {'public_domain': 'test_domain'},
+ 'object': 'test_object',
+ 'deployment_name': 'test_deployment_name'}
+ self.ims_vnf.orchestrator = self.orchestrator
+ self.ims_vnf.images = {'test_image': 'test_url'}
+ self.ims_vnf.vnf = self.orchestrator
+ self.ims_vnf.tenant_name = 'test_tenant'
+ self.ims_vnf.inputs = {'public_domain': 'test_domain'}
+ self.ims_vnf.glance_client = self.glance_client
+ self.ims_vnf.neutron_client = self.neutron_client
+ self.ims_vnf.keystone_client = self.keystone_client
+ self.ims_vnf.nova_client = self.nova_client
+ self.ims_vnf.admin_creds = 'test_creds'
+
+ self.mock_post = mock.Mock()
+ attrs = {'status_code': 201,
+ 'cookies': ""}
+ self.mock_post.configure_mock(**attrs)
+
+ self.mock_post_200 = mock.Mock()
+ attrs = {'status_code': 200,
+ 'cookies': ""}
+ self.mock_post_200.configure_mock(**attrs)
+
+ def test_deploy_orchestrator_missing_image(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_neutron_client',
+ return_value=self.neutron_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_glance_client',
+ return_value=self.glance_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_keystone_client',
+ return_value=self.keystone_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_nova_client',
+ return_value=self.nova_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_image_id',
+ return_value=''), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'download_and_add_image_on_glance') as m, \
+ self.assertRaises(Exception) as context:
+ self.ims_vnf.deploy_orchestrator()
+ self.assertTrue(m.called)
+ msg = "Failed to find or upload required OS "
+ msg += "image for this deployment"
+ self.assertTrue(msg in context.exception)
+
+ def test_deploy_orchestrator_extend_quota_fail(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_neutron_client',
+ return_value=self.neutron_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_glance_client',
+ return_value=self.glance_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_keystone_client',
+ return_value=self.keystone_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_nova_client',
+ return_value=self.nova_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_image_id',
+ return_value='image_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_tenant_id',
+ return_value='tenant_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.update_sg_quota',
+ return_value=False), \
+ self.assertRaises(Exception) as context:
+ self.ims_vnf.deploy_orchestrator()
+ msg = "Failed to update security group quota"
+ msg += " for tenant test_tenant"
+ self.assertTrue(msg in context.exception)
+
+ def _get_image_id(self, client, name):
+ if name == 'test_image':
+ return 'image_id'
+ else:
+ return ''
+
+ def test_deploy_orchestrator_missing_flavor(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_neutron_client',
+ return_value=self.neutron_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_glance_client',
+ return_value=self.glance_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_keystone_client',
+ return_value=self.keystone_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_nova_client',
+ return_value=self.nova_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_image_id',
+ side_effect=self._get_image_id), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_tenant_id',
+ return_value='tenant_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.update_sg_quota',
+ return_value=True), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_endpoint',
+ return_value='public_auth_url'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'Orchestrator', return_value=mock.Mock()) as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_or_create_flavor',
+ return_value=(False, '')), \
+ self.assertRaises(Exception) as context:
+ self.ims_vnf.deploy_orchestrator()
+ self.assertTrue(m.set_credentials.called)
+ msg = "Failed to find required flavorfor this deployment"
+ self.assertTrue(msg in context.exception)
+
+ def test_deploy_orchestrator_missing_os_image(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_neutron_client',
+ return_value=self.neutron_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_glance_client',
+ return_value=self.glance_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_keystone_client',
+ return_value=self.keystone_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_nova_client',
+ return_value=self.nova_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_image_id',
+ side_effect=self._get_image_id), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_tenant_id',
+ return_value='tenant_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.update_sg_quota',
+ return_value=True), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_endpoint',
+ return_value='public_auth_url'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'Orchestrator', return_value=mock.Mock()) as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_or_create_flavor',
+ return_value=(True, 'flavor_id')), \
+ self.assertRaises(Exception) as context:
+ self.ims_vnf.deploy_orchestrator()
+ self.assertTrue(m.set_credentials.called)
+ self.assertTrue(m.set_flavor_id.called)
+ msg = "Failed to find required OS image for cloudify manager"
+ self.assertTrue(msg in context.exception)
+
+ def test_deploy_orchestrator_get_ext_network_fail(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_neutron_client',
+ return_value=self.neutron_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_glance_client',
+ return_value=self.glance_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_keystone_client',
+ return_value=self.keystone_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_nova_client',
+ return_value=self.nova_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_image_id',
+ return_value='image_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_tenant_id',
+ return_value='tenant_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.update_sg_quota',
+ return_value=True), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_endpoint',
+ return_value='public_auth_url'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'Orchestrator', return_value=mock.Mock()) as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_or_create_flavor',
+ return_value=(True, 'flavor_id')), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_external_net',
+ return_value=''), \
+ self.assertRaises(Exception) as context:
+ self.ims_vnf.deploy_orchestrator()
+ self.assertTrue(m.set_credentials.called)
+ self.assertTrue(m.set_flavor_id.called)
+ self.assertTrue(m.set_image_id.called)
+ msg = "Failed to get external network"
+ self.assertTrue(msg in context.exception)
+
+ def test_deploy_orchestrator_with_error(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_neutron_client',
+ return_value=self.neutron_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_glance_client',
+ return_value=self.glance_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_keystone_client',
+ return_value=self.keystone_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_nova_client',
+ return_value=self.nova_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_image_id',
+ return_value='image_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_tenant_id',
+ return_value='tenant_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.update_sg_quota',
+ return_value=True), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_endpoint',
+ return_value='public_auth_url'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'Orchestrator') as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_or_create_flavor',
+ return_value=(True, 'flavor_id')), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_external_net',
+ return_value='ext_net'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'ft_utils.get_resolvconf_ns',
+ return_value=True), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'ft_utils.execute_command'):
+ mock_obj = mock.Mock()
+ attrs = {'deploy_manager.return_value': 'error'}
+ mock_obj.configure_mock(**attrs)
+
+ m.return_value = mock_obj
+
+ self.assertEqual(self.ims_vnf.deploy_orchestrator(),
+ {'status': 'FAIL', 'result': 'error'})
+
+ def test_deploy_orchestrator_default(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_neutron_client',
+ return_value=self.neutron_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_glance_client',
+ return_value=self.glance_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_keystone_client',
+ return_value=self.keystone_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_nova_client',
+ return_value=self.nova_client), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_image_id',
+ return_value='image_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_tenant_id',
+ return_value='tenant_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.update_sg_quota',
+ return_value=True), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_endpoint',
+ return_value='public_auth_url'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'Orchestrator') as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_or_create_flavor',
+ return_value=(True, 'flavor_id')), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_external_net',
+ return_value='ext_net'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'ft_utils.get_resolvconf_ns',
+ return_value=True), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'ft_utils.execute_command'):
+ mock_obj = mock.Mock()
+ attrs = {'deploy_manager.return_value': ''}
+ mock_obj.configure_mock(**attrs)
+
+ m.return_value = mock_obj
+
+ self.assertEqual(self.ims_vnf.deploy_orchestrator(),
+ {'status': 'PASS', 'result': ''})
+
+ def test_deploy_vnf_missing_flavor(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'Clearwater', return_value=mock.Mock()), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_or_create_flavor',
+ return_value=(False, '')), \
+ self.assertRaises(Exception) as context:
+ self.ims_vnf.deploy_vnf()
+ msg = "Failed to find required flavor for this deployment"
+ self.assertTrue(msg in context.exception)
+
+ def test_deploy_vnf_missing_os_image(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'Clearwater', return_value=mock.Mock()) as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_or_create_flavor',
+ return_value=(True, 'test_flavor')), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_image_id',
+ return_value=''), \
+ self.assertRaises(Exception) as context:
+ self.ims_vnf.deploy_vnf()
+ msg = "Failed to find required OS image"
+ msg += " for clearwater VMs"
+ self.assertTrue(msg in context.exception)
+ self.assertTrue(m.set_flavor_id.called)
+
+ def test_deploy_vnf_missing_get_ext_net(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'Clearwater', return_value=mock.Mock()) as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_or_create_flavor',
+ return_value=(True, 'test_flavor')), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_image_id',
+ return_value='image_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_external_net',
+ return_value=''), \
+ self.assertRaises(Exception) as context:
+ self.ims_vnf.deploy_vnf()
+ msg = "Failed to get external network"
+ self.assertTrue(msg in context.exception)
+ self.assertTrue(m.set_flavor_id.called)
+ self.assertTrue(m.set_image_id.called)
+
+ def test_deploy_vnf_with_error(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'Clearwater') as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_or_create_flavor',
+ return_value=(True, 'test_flavor')), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_image_id',
+ return_value='image_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_external_net',
+ return_value='ext_net'):
+ mock_obj = mock.Mock()
+ attrs = {'deploy_vnf.return_value': 'error'}
+ mock_obj.configure_mock(**attrs)
+
+ m.return_value = mock_obj
+
+ self.assertEqual(self.ims_vnf.deploy_vnf(),
+ {'status': 'FAIL', 'result': 'error'})
+
+ def test_deploy_vnf_default(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'Clearwater') as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_or_create_flavor',
+ return_value=(True, 'test_flavor')), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_image_id',
+ return_value='image_id'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.get_external_net',
+ return_value='ext_net'):
+ mock_obj = mock.Mock()
+ attrs = {'deploy_vnf.return_value': ''}
+ mock_obj.configure_mock(**attrs)
+
+ m.return_value = mock_obj
+
+ self.assertEqual(self.ims_vnf.deploy_vnf(),
+ {'status': 'PASS', 'result': ''})
+
+ def test_test_vnf_ip_retrieval_failure(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os.popen', side_effect=Exception), \
+ self.assertRaises(Exception) as context:
+ msg = "Unable to retrieve the IP of the "
+ msg += "cloudify manager server !"
+ self.ims_vnf.test_vnf()
+ self.assertTrue(msg in context.exception)
+
+ def test_test_vnf_create_number_failure(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os.popen') as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'requests.get'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'requests.post',
+ return_value=self.mock_post), \
+ self.assertRaises(Exception) as context:
+ mock_obj = mock.Mock()
+ attrs = {'read.return_value': 'test_ip\n'}
+ mock_obj.configure_mock(**attrs)
+ m.return_value = mock_obj
+
+ self.ims_vnf.test_vnf()
+
+ msg = "Unable to create a number:"
+ self.assertTrue(msg in context.exception)
+
+ def _get_post_status(self, url, cookies='', data=''):
+ ellis_url = "http://test_ellis_ip/session"
+ if url == ellis_url:
+ return self.mock_post_200
+ return self.mock_post
+
+ def test_test_vnf_fail(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os.popen') as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'requests.get') as mock_get, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'requests.post',
+ side_effect=self._get_post_status), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'ft_utils.get_resolvconf_ns'), \
+ mock.patch('__builtin__.open', mock.mock_open()), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'subprocess.call'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os.remove'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'json.load', return_value=''):
+ mock_obj = mock.Mock()
+ attrs = {'read.return_value': 'test_ip\n'}
+ mock_obj.configure_mock(**attrs)
+ m.return_value = mock_obj
+
+ mock_obj2 = mock.Mock()
+ attrs = {'json.return_value': {'outputs':
+ {'dns_ip': 'test_dns_ip',
+ 'ellis_ip': 'test_ellis_ip'}}}
+ mock_obj2.configure_mock(**attrs)
+ mock_get.return_value = mock_obj2
+
+ self.assertEqual(self.ims_vnf.test_vnf(),
+ {'status': 'FAIL', 'result': ''})
+
+ def test_test_vnf_pass(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os.popen') as m, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'requests.get') as mock_get, \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'requests.post',
+ side_effect=self._get_post_status), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'ft_utils.get_resolvconf_ns'), \
+ mock.patch('__builtin__.open', mock.mock_open()), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'subprocess.call'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os.remove'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'json.load', return_value='vims_test_result'):
+ mock_obj = mock.Mock()
+ attrs = {'read.return_value': 'test_ip\n'}
+ mock_obj.configure_mock(**attrs)
+ m.return_value = mock_obj
+
+ mock_obj2 = mock.Mock()
+ attrs = {'json.return_value': {'outputs':
+ {'dns_ip': 'test_dns_ip',
+ 'ellis_ip': 'test_ellis_ip'}}}
+ mock_obj2.configure_mock(**attrs)
+ mock_get.return_value = mock_obj2
+
+ self.assertEqual(self.ims_vnf.test_vnf(),
+ {'status': 'PASS', 'result': 'vims_test_result'})
+
+ def test_download_and_add_image_on_glance_incorrect_url(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os.makedirs'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'ft_utils.download_url',
+ return_value=False):
+ resp = cloudify_ims.download_and_add_image_on_glance(self.
+ glance_client,
+ 'image_name',
+ 'http://url',
+ 'data_dir')
+ self.assertEqual(resp, False)
+
+ def test_download_and_add_image_on_glance_image_creation_failure(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os.makedirs'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'ft_utils.download_url',
+ return_value=True), \
+ mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
+ 'os_utils.create_glance_image',
+ return_value=''):
+ resp = cloudify_ims.download_and_add_image_on_glance(self.
+ glance_client,
+ 'image_name',
+ 'http://url',
+ 'data_dir')
+ self.assertEqual(resp, False)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/opnfv_tests/vnf/ims/test_orchestrator_cloudify.py b/functest/tests/unit/opnfv_tests/vnf/ims/test_orchestrator_cloudify.py
new file mode 100644
index 000000000..620b0216f
--- /dev/null
+++ b/functest/tests/unit/opnfv_tests/vnf/ims/test_orchestrator_cloudify.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import logging
+import unittest
+
+import mock
+
+from functest.opnfv_tests.vnf.ims import orchestrator_cloudify
+
+
+class ImsVnfTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.orchestrator = orchestrator_cloudify.Orchestrator('test_dir')
+ self.bp = {'file_name': 'test_file',
+ 'destination_folder': 'test_folder',
+ 'url': 'test_url',
+ 'branch': 'test_branch'}
+
+ def test_download_manager_blueprint_download_blueprint_failed(self):
+ self.orchestrator.manager_blueprint = False
+ with mock.patch.object(self.orchestrator, '_download_blueprints',
+ return_value=False), \
+ mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'exit') as mock_exit:
+ self.orchestrator.download_manager_blueprint('test_url',
+ 'test_branch')
+ mock_exit.assert_any_call(-1)
+
+ def test_download_manager_blueprint_download_blueprint_passed(self):
+ self.orchestrator.manager_blueprint = False
+ with mock.patch.object(self.orchestrator, '_download_blueprints',
+ return_value=True):
+ self.orchestrator.download_manager_blueprint('test_url',
+ 'test_branch')
+ self.assertEqual(self.orchestrator.manager_blueprint,
+ True)
+
+ def test_deploy_manager_failed(self):
+ self.orchestrator.manager_blueprint = True
+ with mock.patch('__builtin__.open', mock.mock_open()), \
+ mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'os.remove'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'execute_command', return_value='error'):
+ self.assertEqual(self.orchestrator.deploy_manager(),
+ 'error')
+ self.assertEqual(self.orchestrator.manager_up,
+ False)
+
+ def test_deploy_manager_passed(self):
+ self.orchestrator.manager_blueprint = True
+ with mock.patch('__builtin__.open', mock.mock_open()), \
+ mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'os.remove'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'execute_command', return_value=''):
+ self.orchestrator.deploy_manager()
+ self.assertEqual(self.orchestrator.manager_up,
+ True)
+
+ def test_undeploy_manager_passed(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'execute_command', return_value=''):
+ self.orchestrator.deploy_manager()
+ self.assertEqual(self.orchestrator.manager_up,
+ False)
+
+ def test_dwnld_upload_and_depl_blueprint_dwnld_blueprint_failed(self):
+ with mock.patch.object(self.orchestrator, '_download_blueprints',
+ return_value=False), \
+ mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'exit', side_effect=Exception) as mock_exit, \
+ self.assertRaises(Exception):
+ self.orchestrator.download_upload_and_deploy_blueprint(self.bp,
+ 'cfig',
+ 'bpn',
+ 'dpn')
+ mock_exit.assert_any_call(-1)
+
+ def test_dwnld_upload_and_depl_blueprint_failed(self):
+ with mock.patch.object(self.orchestrator, '_download_blueprints',
+ return_value=True), \
+ mock.patch('__builtin__.open', mock.mock_open()), \
+ mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'execute_command', return_value='error'):
+ r = self.orchestrator.download_upload_and_deploy_blueprint(self.bp,
+ 'cfig',
+ 'bpn',
+ 'dpn')
+ self.assertEqual(r, 'error')
+
+ def test__download_blueprints_failed(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'shutil.rmtree'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'Repo.clone_from', side_effect=Exception):
+ self.assertEqual(self.orchestrator._download_blueprints('bp_url',
+ 'branch',
+ 'dest'),
+ False)
+
+ def test__download_blueprints_passed(self):
+ with mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'shutil.rmtree'), \
+ mock.patch('functest.opnfv_tests.vnf.ims.orchestrator_cloudify.'
+ 'Repo.clone_from'):
+ self.assertEqual(self.orchestrator._download_blueprints('bp_url',
+ 'branch',
+ 'dest'),
+ True)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/utils/test_openstack_utils.py b/functest/tests/unit/utils/test_openstack_utils.py
index 447271fc6..ef3764cc5 100644
--- a/functest/tests/unit/utils/test_openstack_utils.py
+++ b/functest/tests/unit/utils/test_openstack_utils.py
@@ -104,7 +104,6 @@ class OSUtilsTesting(unittest.TestCase):
'servers.create.return_value': self.instance,
'flavors.list.return_value': [self.flavor],
'flavors.find.return_value': self.flavor,
- 'flavors.list.return_value': [self.flavor],
'servers.add_floating_ip.return_value': mock.Mock(),
'servers.force_delete.return_value': mock.Mock(),
'aggregates.list.return_value': [self.aggregate],
@@ -162,6 +161,15 @@ class OSUtilsTesting(unittest.TestCase):
}
self.cinder_client.configure_mock(**attrs)
+ self.resource = mock.Mock()
+ attrs = {'id': 'resource_test_id',
+ 'name': 'resource_test_name'
+ }
+
+ self.heat_client = mock.Mock()
+ attrs = {'resources.get.return_value': self.resource}
+ self.heat_client.configure_mock(**attrs)
+
mock_obj = mock.Mock()
attrs = {'id': 'tenant_id',
'name': 'test_tenant'}
@@ -543,6 +551,36 @@ class OSUtilsTesting(unittest.TestCase):
mock_glan_client.assert_called_once_with('3',
session=mock_session_obj)
+ @mock.patch('functest.utils.openstack_utils.os.getenv',
+ return_value=None)
+ def test_get_heat_client_version_missing_env(self, mock_os_getenv):
+ self.assertEqual(openstack_utils.get_heat_client_version(),
+ openstack_utils.DEFAULT_HEAT_API_VERSION)
+
+ @mock.patch('functest.utils.openstack_utils.logger.info')
+ @mock.patch('functest.utils.openstack_utils.os.getenv', return_value='1')
+ def test_get_heat_client_version_default(self, mock_os_getenv,
+ mock_logger_info):
+ self.assertEqual(openstack_utils.get_heat_client_version(), '1')
+ mock_logger_info.assert_called_once_with(
+ "OS_ORCHESTRATION_API_VERSION is set in env as '%s'", '1')
+
+ def test_get_heat_client(self):
+ mock_heat_obj = mock.Mock()
+ mock_session_obj = mock.Mock()
+ with mock.patch('functest.utils.openstack_utils'
+ '.get_heat_client_version', return_value='1'), \
+ mock.patch('functest.utils.openstack_utils'
+ '.heatclient.Client',
+ return_value=mock_heat_obj) \
+ as mock_heat_client, \
+ mock.patch('functest.utils.openstack_utils.get_session',
+ return_value=mock_session_obj):
+ self.assertEqual(openstack_utils.get_heat_client(),
+ mock_heat_obj)
+ mock_heat_client.assert_called_once_with('1',
+ session=mock_session_obj)
+
def test_get_instances_default(self):
self.assertEqual(openstack_utils.get_instances(self.nova_client),
[self.instance])
@@ -1700,6 +1738,24 @@ class OSUtilsTesting(unittest.TestCase):
'user_id'))
self.assertTrue(mock_logger_error.called)
+ def test_get_resource_default(self):
+ with mock.patch('functest.utils.openstack_utils.'
+ 'is_keystone_v3', return_value=True):
+ self.assertEqual(openstack_utils.
+ get_resource(self.heat_client,
+ 'stack_id',
+ 'resource'),
+ self.resource)
+
+ @mock.patch('functest.utils.openstack_utils.logger.error')
+ def test_get_resource_exception(self, mock_logger_error):
+ self.assertEqual(openstack_utils.
+ get_resource(Exception,
+ 'stack_id',
+ 'resource'),
+ None)
+ self.assertTrue(mock_logger_error.called)
+
if __name__ == "__main__":
unittest.main(verbosity=2)
diff --git a/functest/utils/config.py b/functest/utils/config.py
index 84166c1d3..b5b845010 100644..100755
--- a/functest/utils/config.py
+++ b/functest/utils/config.py
@@ -2,26 +2,25 @@ import os
import yaml
+import env
+
class Config(object):
def __init__(self):
- if 'CONFIG_FUNCTEST_YAML' not in os.environ:
- raise Exception('CONFIG_FUNCTEST_YAML not configed')
- self.config_functest = os.environ['CONFIG_FUNCTEST_YAML']
try:
- with open(self.config_functest) as f:
+ with open(env.ENV.CONFIG_FUNCTEST_YAML) as f:
self.functest_yaml = yaml.safe_load(f)
self._parse(None, self.functest_yaml)
- except:
- raise Exception('Parse {} failed'.format(self.config_functest))
+ except Exception as error:
+ raise Exception('Parse config failed: {}'.format(str(error)))
self._set_others()
def _parse(self, attr_now, left_parametes):
for param_n, param_v in left_parametes.iteritems():
attr_further = self._get_attr_further(attr_now, param_n)
- if not isinstance(param_v, dict):
+ if attr_further:
self.__setattr__(attr_further, param_v)
- else:
+ if isinstance(param_v, dict):
self._parse(attr_further, param_v)
def _get_attr_further(self, attr_now, next):
@@ -33,3 +32,8 @@ class Config(object):
CONF = Config()
+
+if __name__ == "__main__":
+ print CONF.vnf_cloudify_ims
+ print CONF.vnf_cloudify_ims_tenant_images
+ print CONF.vnf_cloudify_ims_tenant_images_centos_7
diff --git a/functest/utils/openstack_utils.py b/functest/utils/openstack_utils.py
index 3093cb558..e33af63b4 100755
--- a/functest/utils/openstack_utils.py
+++ b/functest/utils/openstack_utils.py
@@ -18,6 +18,7 @@ from keystoneauth1 import loading
from keystoneauth1 import session
from cinderclient import client as cinderclient
from glanceclient import client as glanceclient
+from heatclient import client as heatclient
from novaclient import client as novaclient
from keystoneclient import client as keystoneclient
from neutronclient.neutron import client as neutronclient
@@ -28,6 +29,7 @@ import functest.utils.functest_utils as ft_utils
logger = ft_logger.Logger("openstack_utils").getLogger()
DEFAULT_API_VERSION = '2'
+DEFAULT_HEAT_API_VERSION = '1'
# *********************************************
@@ -241,6 +243,20 @@ def get_glance_client(other_creds={}):
return glanceclient.Client(get_glance_client_version(), session=sess)
+def get_heat_client_version():
+ api_version = os.getenv('OS_ORCHESTRATION_API_VERSION')
+ if api_version is not None:
+ logger.info("OS_ORCHESTRATION_API_VERSION is set in env as '%s'",
+ api_version)
+ return api_version
+ return DEFAULT_HEAT_API_VERSION
+
+
+def get_heat_client(other_creds={}):
+ sess = get_session(other_creds)
+ return heatclient.Client(get_heat_client_version(), session=sess)
+
+
# *********************************************
# NOVA
# *********************************************
@@ -985,36 +1001,43 @@ def create_security_group(neutron_client, sg_name, sg_description):
def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
port_range_min=None, port_range_max=None):
- if port_range_min is None and port_range_max is None:
- json_body = {'security_group_rule': {'direction': direction,
- 'security_group_id': sg_id,
- 'protocol': protocol}}
- elif port_range_min is not None and port_range_max is not None:
- json_body = {'security_group_rule': {'direction': direction,
- 'security_group_id': sg_id,
- 'port_range_min': port_range_min,
- 'port_range_max': port_range_max,
- 'protocol': protocol}}
+ # We create a security group in 2 steps
+ # 1 - we check the format and set the json body accordingly
+ # 2 - we call neturon client to create the security group
+
+ # Format check
+ json_body = {'security_group_rule': {'direction': direction,
+ 'security_group_id': sg_id,
+ 'protocol': protocol}}
+ # parameters may be
+ # - both None => we do nothing
+ # - both Not None => we add them to the json description
+ # but one cannot be None is the other is not None
+ if (port_range_min is not None and port_range_max is not None):
+ # add port_range in json description
+ json_body['security_group_rule']['port_range_min'] = port_range_min
+ json_body['security_group_rule']['port_range_max'] = port_range_max
+ logger.debug("Security_group format set (port range included)")
else:
- logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
- "'%s', '%s', '%s', '%s')]:" % (neutron_client,
- sg_id, direction,
- port_range_min,
- port_range_max,
- protocol),
- " Invalid values for port_range_min, port_range_max")
- return False
+ # either both port range are set to None => do nothing
+ # or one is set but not the other => log it and return False
+ if port_range_min is None and port_range_max is None:
+ logger.debug("Security_group format set (no port range mentioned)")
+ else:
+ logger.error("Bad security group format."
+ "One of the port range is not properly set:"
+ "range min: {},"
+ "range max: {}".format(port_range_min,
+ port_range_max))
+ return False
+
+ # Create security group using neutron client
try:
neutron_client.create_security_group_rule(json_body)
return True
- except Exception, e:
- logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
- "'%s', '%s', '%s', '%s')]: %s" % (neutron_client,
- sg_id,
- direction,
- port_range_min,
- port_range_max,
- protocol, e))
+ except:
+ logger.exception("Impossible to create_security_group_rule,"
+ "security group rule probably already exists")
return False
@@ -1383,3 +1406,15 @@ def delete_user(keystone_client, user_id):
logger.error("Error [delete_user(keystone_client, '%s')]: %s"
% (user_id, e))
return False
+
+
+# *********************************************
+# HEAT
+# *********************************************
+def get_resource(heat_client, stack_id, resource):
+ try:
+ resources = heat_client.resources.get(stack_id, resource)
+ return resources
+ except Exception, e:
+ logger.error("Error [get_resource]: %s" % e)
+ return None