summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docker/vnf/Dockerfile8
-rw-r--r--docker/vnf/testcases.yaml17
-rw-r--r--docs/testing/user/userguide/test_details.rst22
-rw-r--r--functest/ci/config_functest.yaml6
-rw-r--r--functest/ci/testcases.yaml17
-rw-r--r--functest/opnfv_tests/openstack/shaker/shaker.py24
-rw-r--r--functest/opnfv_tests/vnf/ims/clearwater.py (renamed from functest/opnfv_tests/vnf/ims/clearwater_ims_base.py)124
-rw-r--r--functest/opnfv_tests/vnf/ims/cloudify_ims.py47
-rw-r--r--functest/opnfv_tests/vnf/ims/cloudify_ims.yaml29
-rw-r--r--functest/opnfv_tests/vnf/ims/heat_ims.py256
-rw-r--r--functest/opnfv_tests/vnf/ims/heat_ims.yaml22
-rw-r--r--functest/tests/unit/vnf/ims/test_clearwater.py (renamed from functest/tests/unit/vnf/ims/test_ims_base.py)6
12 files changed, 469 insertions, 109 deletions
diff --git a/docker/vnf/Dockerfile b/docker/vnf/Dockerfile
index 09bb6fb5a..192c528ad 100644
--- a/docker/vnf/Dockerfile
+++ b/docker/vnf/Dockerfile
@@ -4,7 +4,8 @@ ARG BRANCH=master
ARG OPENSTACK_TAG=stable/queens
ARG VIMS_TEST_TAG=release-129
ARG QUAFF_TAG=59213d6d8ee29433552bb75f505cdc96b0b18909
-ARG VIMS_TAG=fraser
+ARG CLOUDIFY_VIMS_TAG=fraser
+ARG HEAT_VIMS_TAG=release-129
ARG VROUTER_TAG=fraser
ARG JUJU_TAG=tags/juju-2.2.5
@@ -27,7 +28,8 @@ RUN apk --no-cache add --update \
git clone https://github.com/Metaswitch/quaff /src/vims-test/quaff && \
(cd /src/vims-test/quaff && git checkout $QUAFF_TAG) && \
git clone --depth 1 -b $VIMS_TEST_TAG https://github.com/Metaswitch/clearwater-build-infra /src/vims-test/build-infra && \
- git clone --depth 1 -b $VIMS_TAG https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater.git /src/vims && \
+ git clone --depth 1 -b $CLOUDIFY_VIMS_TAG https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater.git /src/cloudify_vims && \
+ git clone --depth 1 -b $HEAT_VIMS_TAG https://github.com/Metaswitch/clearwater-heat.git /src/heat_vims && \
git clone --depth 1 -b $VROUTER_TAG https://github.com/oolorg/opnfv-vnf-vyos-blueprint.git /src/opnfv-vnf-vyos-blueprint && \
git clone https://github.com/RebacaInc/abot_charm.git /src/epc-requirements/abot_charm && \
python3 -m pip install --no-cache-dir --src /src -cupper-constraints.txt -cupper-constraints.opnfv.txt \
@@ -38,7 +40,7 @@ RUN apk --no-cache add --update \
go install -v github.com/juju/juju/... && \
rm -r $GOPATH/src/ $GOPATH/pkg && \
(cd /src/vims-test && bundle config build.nokogiri --use-system-libraries && bundle install --system) && \
- rm -r upper-constraints.txt upper-constraints.opnfv.txt /src/vims-test/.git /src/vims/.git /src/vims-test/quaff/.git \
+ rm -r upper-constraints.txt upper-constraints.opnfv.txt /src/vims-test/.git /src/cloudify_vims/.git /src/heat_vims/.git /src/vims-test/quaff/.git \
/src/vims-test/build-infra/.git /src/opnfv-vnf-vyos-blueprint/.git \
/src/epc-requirements/abot_charm/.git && \
apk del .build-deps
diff --git a/docker/vnf/testcases.yaml b/docker/vnf/testcases.yaml
index 1b2bd9822..1f0817708 100644
--- a/docker/vnf/testcases.yaml
+++ b/docker/vnf/testcases.yaml
@@ -21,7 +21,7 @@ tiers:
-
case_name: cloudify_ims
project_name: functest
- criteria: 80
+ criteria: 100
blocking: false
description: >-
This test case deploys an OpenSource vIMS solution from
@@ -34,6 +34,21 @@ tiers:
class: 'CloudifyIms'
-
+ case_name: heat_ims
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case deploys an OpenSource vIMS solution from
+ Clearwater using the OpenStack Heat orchestrator.
+ It also runs some signaling traffic.
+ dependencies:
+ - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
+ run:
+ module: 'functest.opnfv_tests.vnf.ims.heat_ims'
+ class: 'HeatIms'
+
+ -
case_name: vyos_vrouter
project_name: functest
criteria: 100
diff --git a/docs/testing/user/userguide/test_details.rst b/docs/testing/user/userguide/test_details.rst
index 992b546f5..03020f70e 100644
--- a/docs/testing/user/userguide/test_details.rst
+++ b/docs/testing/user/userguide/test_details.rst
@@ -376,6 +376,27 @@ The Clearwater architecture is described as follows:
:align: center
:alt: vIMS architecture
+heat_ims
+^^^^^^^^
+The IP Multimedia Subsystem or IP Multimedia Core Network Subsystem (IMS) is an
+architectural framework for delivering IP multimedia services.
+
+vIMS has been integrated in Functest to demonstrate the capability to deploy a
+relatively complex NFV scenario on the OPNFV platform. The deployment of a
+complete functional VNF allows the test of most of the essential functions
+needed for a NFV platform.
+
+The goal of this test suite consists of:
+
+* deploy a Clearwater vIMS (IP Multimedia Subsystem) VNF using
+ OpenStack Heat orchestrator based on a HOT template defined in `[17]`_
+* run suite of signaling tests on top of this VNF
+
+The Clearwater architecture is described as follows:
+
+.. figure:: ../../../images/clearwater-architecture-v2.png
+ :align: center
+ :alt: vIMS architecture
vyos-vrouter
^^^^^^^^^^^^
@@ -466,3 +487,4 @@ The kubernetes testcases are distributed across various Tiers:
.. _`[14]`: https://github.com/oolorg/opnfv-functest-vrouter
.. _`[15]`: https://www.rebaca.com/abot-test-orchestration-tool/
.. _`[16]`: https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-tests.md
+.. _`[17]`: https://github.com/Metaswitch/clearwater-heat/blob/release-129/clearwater.yaml
diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml
index 5aa02be68..7e51ee790 100644
--- a/functest/ci/config_functest.yaml
+++ b/functest/ci/config_functest.yaml
@@ -165,10 +165,8 @@ vnf:
tenant_name: cloudify_ims
tenant_description: vIMS
config: cloudify_ims.yaml
- cloudify_ims_perf:
- tenant_name: cloudify_ims_perf
- tenant_description: vIMS
- config: cloudify_ims_perf.yaml
+ heat_ims:
+ config: heat_ims.yaml
orchestra_openims:
tenant_name: orchestra_openims
tenant_description: OpenIMS deployed with Open Baton
diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml
index ecd1d800c..511935e6b 100644
--- a/functest/ci/testcases.yaml
+++ b/functest/ci/testcases.yaml
@@ -479,7 +479,7 @@ tiers:
-
case_name: cloudify_ims
project_name: functest
- criteria: 80
+ criteria: 100
blocking: false
description: >-
This test case deploys an OpenSource vIMS solution from
@@ -492,6 +492,21 @@ tiers:
class: 'CloudifyIms'
-
+ case_name: heat_ims
+ project_name: functest
+ criteria: 100
+ blocking: false
+ description: >-
+ This test case deploys an OpenSource vIMS solution from
+ Clearwater using the OpenStack Heat orchestrator.
+ It also runs some signaling traffic.
+ dependencies:
+ - DEPLOY_SCENARIO: 'os-.*-nofeature-.*ha'
+ run:
+ module: 'functest.opnfv_tests.vnf.ims.heat_ims'
+ class: 'HeatIms'
+
+ -
case_name: vyos_vrouter
project_name: functest
criteria: 100
diff --git a/functest/opnfv_tests/openstack/shaker/shaker.py b/functest/opnfv_tests/openstack/shaker/shaker.py
index dfe1d9c98..097d9b2a7 100644
--- a/functest/opnfv_tests/openstack/shaker/shaker.py
+++ b/functest/opnfv_tests/openstack/shaker/shaker.py
@@ -39,6 +39,10 @@ class Shaker(singlevm.SingleVm2):
ssh_connect_loops = 12
create_server_timeout = 360
+ def __init__(self, **kwargs):
+ super(Shaker, self).__init__(**kwargs)
+ self.role = None
+
def prepare(self):
super(Shaker, self).prepare()
self.cloud.create_security_group_rule(
@@ -54,10 +58,18 @@ class Shaker(singlevm.SingleVm2):
assert self.ssh
endpoint = self.get_public_auth_url(self.orig_cloud)
self.__logger.debug("keystone endpoint: %s", endpoint)
+ if self.orig_cloud.get_role("admin"):
+ role_name = "admin"
+ elif self.orig_cloud.get_role("Admin"):
+ role_name = "Admin"
+ else:
+ raise Exception("Cannot detect neither admin nor Admin")
self.orig_cloud.grant_role(
- "admin", user=self.project.user.id,
+ role_name, user=self.project.user.id,
project=self.project.project.id,
domain=self.project.domain.id)
+ if not self.orig_cloud.get_role("heat_stack_owner"):
+ self.role = self.orig_cloud.create_role("heat_stack_owner")
self.orig_cloud.grant_role(
"heat_stack_owner", user=self.project.user.id,
project=self.project.project.id,
@@ -72,6 +84,9 @@ class Shaker(singlevm.SingleVm2):
'export OS_AUTH_URL={} && '
'export OS_USERNAME={} && '
'export OS_PROJECT_NAME={} && '
+ 'export OS_PROJECT_ID={} && '
+ 'unset OS_TENANT_NAME && '
+ 'unset OS_TENANT_ID && '
'export OS_PASSWORD={} && '
'{}'
'env && '
@@ -83,7 +98,7 @@ class Shaker(singlevm.SingleVm2):
'openstack/perf_l3_north_south '
'--report report.html --output report.json'.format(
endpoint, self.project.user.name, self.project.project.name,
- self.project.password,
+ self.project.project.id, self.project.password,
'export OS_CACERT=~/os_cacert && ' if os.environ.get(
'OS_CACERT') else '',
self.image.name, self.flavor.name,
@@ -99,3 +114,8 @@ class Shaker(singlevm.SingleVm2):
self.__logger.exception("cannot get report files")
return 1
return stdout.channel.recv_exit_status()
+
+ def clean(self):
+ super(Shaker, self).clean()
+ if self.role:
+ self.orig_cloud.delete_role(self.role.id)
diff --git a/functest/opnfv_tests/vnf/ims/clearwater_ims_base.py b/functest/opnfv_tests/vnf/ims/clearwater.py
index 34d3c628d..96f1b40c6 100644
--- a/functest/opnfv_tests/vnf/ims/clearwater_ims_base.py
+++ b/functest/opnfv_tests/vnf/ims/clearwater.py
@@ -27,10 +27,10 @@ __author__ = ("Valentin Boucher <valentin.boucher@orange.com>, "
"Helen Yao <helanyao@gmail.com>")
-class ClearwaterOnBoardingBase(object):
+class ClearwaterTesting(object):
"""vIMS clearwater base usable by several orchestrators"""
- def __init__(self, case_name):
+ def __init__(self, case_name, ellis_ip):
self.logger = logging.getLogger(__name__)
self.case_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/vnf/ims')
@@ -44,54 +44,38 @@ class ClearwaterOnBoardingBase(object):
if not os.path.exists(self.result_dir):
os.makedirs(self.result_dir)
- def config_ellis(self, ellis_ip, signup_code='secret', two_numbers=False):
+ self.ellis_ip = ellis_ip
+
+ def availability_check_by_creating_numbers(self,
+ signup_code='secret',
+ two_numbers=False):
"""Create one or two numbers"""
+ assert self.ellis_ip
output_dict = {}
- self.logger.debug('Configure Ellis: %s', ellis_ip)
- output_dict['ellis_ip'] = ellis_ip
- account_url = 'http://{0}/accounts'.format(ellis_ip)
+ self.logger.debug('Ellis IP: %s', self.ellis_ip)
+ output_dict['ellis_ip'] = self.ellis_ip
+ account_url = 'http://{0}/accounts'.format(self.ellis_ip)
params = {"password": "functest",
"full_name": "opnfv functest user",
"email": "functest@opnfv.org",
"signup_code": signup_code}
- req = requests.post(account_url, data=params)
output_dict['login'] = params
- if req.status_code != 201 and req.status_code != 409:
- raise Exception(
- "Unable to create an account {}\n{}".format(
- params, req.text))
- self.logger.debug(
- 'Account %s is created on Ellis\n%s', params, req.json())
-
- session_url = 'http://{0}/session'.format(ellis_ip)
+
+ number_res = self._create_ellis_account(account_url, params)
+ output_dict['number'] = number_res
+
+ session_url = 'http://{0}/session'.format(self.ellis_ip)
session_data = {
'username': params['email'],
'password': params['password'],
'email': params['email']
}
- req = requests.post(session_url, data=session_data)
- if req.status_code != 201:
- raise Exception('Failed to get cookie for Ellis\n{}'.format(
- req.text))
- cookies = req.cookies
- self.logger.debug('Cookies: %s', cookies)
+ cookies = self._get_ellis_session_cookies(session_url, session_data)
number_url = 'http://{0}/accounts/{1}/numbers'.format(
- ellis_ip, params['email'])
+ self.ellis_ip, params['email'])
self.logger.debug('Create 1st calling number on Ellis')
- i = 30
- while req.status_code != 200 and i > 0:
- try:
- number_res = self._create_ellis_number(number_url, cookies)
- break
- except Exception: # pylint: disable=broad-except
- if i == 1:
- self.logger.exception("Unable to create a number")
- raise Exception("Unable to create a number")
- self.logger.info("Unable to create a number. Retry ..")
- time.sleep(25)
- i = i - 1
- output_dict['number'] = number_res
+ number_res = self._create_ellis_number(number_url, cookies)
if two_numbers:
self.logger.debug('Create 2nd calling number on Ellis')
@@ -100,18 +84,66 @@ class ClearwaterOnBoardingBase(object):
return output_dict
+ def _create_ellis_account(self, account_url, params):
+ i = 50
+ for iloop in range(i):
+ try:
+ req = requests.post(account_url, data=params)
+ if req.status_code == 201:
+ account_res = req.json()
+ self.logger.info(
+ 'Account %s is created on Ellis\n%s',
+ params.get('full_name'), account_res)
+ return account_res
+ else:
+ raise Exception("Cannot create ellis account")
+ except Exception: # pylint: disable=broad-except
+ self.logger.info(
+ "try %s: cannot create ellis account", iloop + 1)
+ time.sleep(25)
+ raise Exception(
+ "Unable to create an account {}".format(
+ params.get('full_name')))
+
+ def _get_ellis_session_cookies(self, session_url, params):
+ i = 15
+ for iloop in range(i):
+ try:
+ req = requests.post(session_url, data=params)
+ if req.status_code == 201:
+ cookies = req.cookies
+ self.logger.debug('cookies: %s', cookies)
+ return cookies
+ else:
+ raise Exception('Failed to get cookies for Ellis')
+ except Exception: # pylint: disable=broad-except
+ self.logger.info(
+ "try %s: cannot get cookies for Ellis", iloop + 1)
+ time.sleep(10)
+ raise Exception('Failed to get cookies for Ellis')
+
def _create_ellis_number(self, number_url, cookies):
- req = requests.post(number_url, cookies=cookies)
-
- if req.status_code != 200:
- if req and req.json():
- reason = req.json()['reason']
- else:
- reason = req
- raise Exception("Unable to create a number: %s" % reason)
- number_res = req.json()
- self.logger.info('Calling number is created: %s', number_res)
- return number_res
+ i = 30
+ for iloop in range(i):
+ try:
+ req = requests.post(number_url, cookies=cookies)
+ if req.status_code == 200:
+ number_res = req.json()
+ self.logger.info(
+ 'Calling number is created: %s', number_res)
+ return number_res
+ else:
+ if req and req.json():
+ reason = req.json()['reason']
+ else:
+ reason = req
+ self.logger.info("cannot create a number: %s", reason)
+ raise Exception('Failed to create a number')
+ except Exception: # pylint: disable=broad-except
+ self.logger.info(
+ "try %s: cannot create a number", iloop + 1)
+ time.sleep(25)
+ raise Exception('Failed to create a number')
def run_clearwater_live_test(self, dns_ip, public_domain,
bono_ip=None, ellis_ip=None,
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
index 36862bd43..7ec647c69 100644
--- a/functest/opnfv_tests/vnf/ims/cloudify_ims.py
+++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py
@@ -22,7 +22,7 @@ import scp
import six
from functest.core import cloudify
-from functest.opnfv_tests.vnf.ims import clearwater_ims_base
+from functest.opnfv_tests.vnf.ims import clearwater
from functest.utils import config
from functest.utils import env
@@ -61,20 +61,17 @@ class CloudifyIms(cloudify.Cloudify):
self.case_dir = pkg_resources.resource_filename(
'functest', 'opnfv_tests/vnf/ims')
config_file = os.path.join(self.case_dir, self.config)
- self.orchestrator = dict(
- requirements=get_config("orchestrator.requirements", config_file),
- )
+
self.details['orchestrator'] = dict(
name=get_config("orchestrator.name", config_file),
version=get_config("orchestrator.version", config_file),
status='ERROR',
result=''
)
- self.__logger.debug("Orchestrator configuration %s", self.orchestrator)
+
self.vnf = dict(
descriptor=get_config("vnf.descriptor", config_file),
- inputs=get_config("vnf.inputs", config_file),
- requirements=get_config("vnf.requirements", config_file)
+ inputs=get_config("vnf.inputs", config_file)
)
self.details['vnf'] = dict(
descriptor_version=self.vnf['descriptor']['version'],
@@ -90,6 +87,7 @@ class CloudifyIms(cloudify.Cloudify):
self.image_alt = None
self.flavor_alt = None
+ self.clearwater = None
def check_requirements(self):
if env.get('NEW_USER_ROLE').lower() == "admin":
@@ -194,33 +192,34 @@ class CloudifyIms(cloudify.Cloudify):
execution = wait_for_execution(
self.cfy_client, execution, self.__logger, timeout=3600)
- duration = time.time() - start_time
-
self.__logger.info(execution)
- if execution.status == 'terminated':
- self.details['vnf'].update(status='PASS', duration=duration)
- self.result += 1/3 * 100
- result = True
- else:
- self.details['vnf'].update(status='FAIL', duration=duration)
- result = False
- return result
+ if execution.status != 'terminated':
+ self.details['vnf'].update(status='FAIL',
+ duration=time.time() - start_time)
+ return False
+
+ ellis_ip = self.cfy_client.deployments.outputs.get(
+ self.vnf['descriptor'].get('name'))['outputs']['ellis_ip']
+ self.clearwater = clearwater.ClearwaterTesting(self.case_name,
+ ellis_ip)
+ self.clearwater.availability_check_by_creating_numbers()
+
+ self.details['vnf'].update(status='PASS',
+ duration=time.time() - start_time)
+ self.result += 1/3 * 100
+ return True
def test_vnf(self):
"""Run test on clearwater ims instance."""
start_time = time.time()
- testing = clearwater_ims_base.ClearwaterOnBoardingBase(self.case_name)
- outputs = self.cfy_client.deployments.outputs.get(
- self.vnf['descriptor'].get('name'))['outputs']
- dns_ip = outputs['dns_ip']
- ellis_ip = outputs['ellis_ip']
- testing.config_ellis(ellis_ip)
+ dns_ip = self.cfy_client.deployments.outputs.get(
+ self.vnf['descriptor'].get('name'))['outputs']['dns_ip']
if not dns_ip:
return False
- short_result = testing.run_clearwater_live_test(
+ short_result = self.clearwater.run_clearwater_live_test(
dns_ip=dns_ip,
public_domain=self.vnf['inputs']["public_domain"])
duration = time.time() - start_time
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml b/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml
index 6808cf33d..869281a20 100644
--- a/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml
+++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml
@@ -1,35 +1,14 @@
---
-tenant_images:
- ubuntu_14.04:
- /home/opnfv/functest/images/ubuntu-14.04-server-cloudimg-amd64-disk1.img
- cloudify_manager_4.0:
- /home/opnfv/functest/images/cloudify-manager-premium-4.0.1.qcow2
orchestrator:
name: cloudify
version: '4.0'
- requirements:
- flavor:
- name: cloudify.medium
- ram_min: 4096
- os_image: 'cloudify_manager_4.0'
vnf:
name: clearwater
- version: '107'
+ version: '129'
descriptor:
- file_name: /src/vims/openstack-blueprint.yaml
+ file_name: /src/cloudify_vims/openstack-blueprint.yaml
name: clearwater-opnfv
- version: '122'
- requirements:
- flavor:
- name: cloudify.small
- ram_min: 2048
- compute_quotas:
- cores: 50
- instances: 15
- network_quotas:
- security_group: 20
- security_group_rule: 100
- port: 50
+ version: '129'
inputs:
image_id: 'ubuntu_14.04'
flavor_id: 'cloudify.small'
@@ -46,4 +25,4 @@ vnf:
homer_cluster_size: 1
vnf_test_suite:
name: clearwater-live-test
- version: "1.0"
+ version: '1.0'
diff --git a/functest/opnfv_tests/vnf/ims/heat_ims.py b/functest/opnfv_tests/vnf/ims/heat_ims.py
new file mode 100644
index 000000000..32783dae7
--- /dev/null
+++ b/functest/opnfv_tests/vnf/ims/heat_ims.py
@@ -0,0 +1,256 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2018 Kontron, Orange 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
+
+"""HeatIms testcase implementation."""
+
+from __future__ import division
+
+import logging
+import os
+import re
+import time
+import yaml
+
+import pkg_resources
+from xtesting.core import testcase
+
+from functest.core import singlevm
+from functest.opnfv_tests.vnf.ims import clearwater
+from functest.utils import config
+from functest.utils import env
+
+__author__ = "Valentin Boucher <valentin.boucher@kontron.com>"
+
+
+class HeatIms(singlevm.VmReady2):
+ # pylint: disable=too-many-instance-attributes
+ """Clearwater vIMS deployed with Heat Orchestrator Case."""
+
+ __logger = logging.getLogger(__name__)
+
+ filename_alt = ('/home/opnfv/functest/images/'
+ 'ubuntu-14.04-server-cloudimg-amd64-disk1.img')
+
+ flavor_alt_ram = 2048
+ flavor_alt_vcpus = 2
+ flavor_alt_disk = 25
+
+ quota_security_group = 20
+ quota_security_group_rule = 100
+ quota_port = 50
+
+ def __init__(self, **kwargs):
+ """Initialize HeatIms testcase object."""
+ if "case_name" not in kwargs:
+ kwargs["case_name"] = "heat_ims"
+ super(HeatIms, self).__init__(**kwargs)
+
+ # Retrieve the configuration
+ try:
+ self.config = getattr(
+ config.CONF, 'vnf_{}_config'.format(self.case_name))
+ except Exception:
+ raise Exception("VNF config file not found")
+
+ self.case_dir = pkg_resources.resource_filename(
+ 'functest', 'opnfv_tests/vnf/ims')
+ config_file = os.path.join(self.case_dir, self.config)
+
+ self.vnf = dict(
+ descriptor=get_config("vnf.descriptor", config_file),
+ parameters=get_config("vnf.inputs", config_file)
+ )
+ self.details['vnf'] = dict(
+ descriptor_version=self.vnf['descriptor']['version'],
+ name=get_config("vnf.name", config_file),
+ version=get_config("vnf.version", config_file),
+ )
+ self.__logger.debug("VNF configuration: %s", self.vnf)
+
+ self.image_alt = None
+ self.flavor_alt = None
+ self.keypair = None
+ self.stack = None
+ self.clearwater = None
+ self.role = None
+
+ def execute(self):
+ # pylint: disable=too-many-locals,too-many-statements
+ """
+ Prepare Tenant/User
+
+ network, security group, fip, VM creation
+ """
+ self.orig_cloud.set_network_quotas(
+ self.project.project.name,
+ security_group=self.quota_security_group,
+ security_group_rule=self.quota_security_group_rule,
+ port=self.quota_port)
+ if not self.orig_cloud.get_role("heat_stack_owner"):
+ self.role = self.orig_cloud.create_role("heat_stack_owner")
+ self.orig_cloud.grant_role(
+ "heat_stack_owner", user=self.project.user.id,
+ project=self.project.project.id,
+ domain=self.project.domain.id)
+ self.keypair = self.cloud.create_keypair(
+ '{}-kp_{}'.format(self.case_name, self.guid))
+ self.__logger.debug("keypair: %s", self.keypair)
+
+ if (self.deploy_vnf() and self.test_vnf()):
+ self.result = 100
+ return 0
+ self.result = 1/3 * 100
+ return 1
+
+ def run(self, **kwargs):
+ """Deploy and test clearwater
+
+ Here are the main actions:
+ - deploy clearwater stack via heat
+ - test the vnf instance
+
+ Returns:
+ - TestCase.EX_OK
+ - TestCase.EX_RUN_ERROR on error
+ """
+ status = testcase.TestCase.EX_RUN_ERROR
+ try:
+ assert self.cloud
+ self.start_time = time.time()
+ self.result = 0
+ if not self.execute():
+ self.result = 100
+ status = testcase.TestCase.EX_OK
+ except Exception: # pylint: disable=broad-except
+ self.__logger.exception('Cannot run %s', self.case_name)
+ finally:
+ self.stop_time = time.time()
+ return status
+
+ def deploy_vnf(self):
+ """Deploy Clearwater IMS."""
+ start_time = time.time()
+
+ self.image_alt = self.publish_image_alt()
+ self.flavor_alt = self.create_flavor_alt()
+ # KeyPair + Image + Flavor OK
+
+ descriptor = self.vnf['descriptor']
+ parameters = self.vnf['parameters']
+
+ parameters['public_mgmt_net_id'] = self.ext_net.id
+ parameters['public_sig_net_id'] = self.ext_net.id
+ parameters['flavor'] = self.flavor_alt.name
+ parameters['image'] = self.image_alt.name
+ parameters['key_name'] = self.keypair.name
+ parameters['external_mgmt_dns_ip'] = env.get('NAMESERVER')
+ parameters['external_sig_dns_ip'] = env.get('NAMESERVER')
+
+ self.__logger.info("Create Heat Stack")
+ self.stack = self.cloud.create_stack(
+ name=descriptor.get('name'),
+ template_file=descriptor.get('file_name'),
+ wait=True, **parameters)
+ self.__logger.debug("stack: %s", self.stack)
+
+ servers = self.cloud.list_servers(detailed=True)
+ self.__logger.debug("servers: %s", servers)
+ for server in servers:
+ if not self.check_regex_in_console(
+ server.name, regex='Cloud-init .* finished at ', loop=60):
+ return False
+ if 'ellis' in server.name:
+ self.__logger.debug("server: %s", server)
+ ellis_ip = server.public_v4
+
+ assert ellis_ip
+ self.clearwater = clearwater.ClearwaterTesting(self.case_name,
+ ellis_ip)
+ # This call can take time and many retry because Heat is
+ # an infrastructure orchestrator so when Heat say "stack created"
+ # it means that all OpenStack ressources are created but not that
+ # Clearwater are up and ready (Cloud-Init script still running)
+ self.clearwater.availability_check_by_creating_numbers()
+
+ duration = time.time() - start_time
+
+ self.details['vnf'].update(status='PASS', duration=duration)
+ self.result += 1/3 * 100
+
+ return True
+
+ def test_vnf(self):
+ """Run test on clearwater ims instance."""
+ start_time = time.time()
+
+ outputs = self.cloud.get_stack(self.stack.id).outputs
+ self.__logger.debug("stack outputs: %s", outputs)
+ dns_ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', str(outputs))[0]
+
+ if not dns_ip:
+ return False
+
+ short_result = self.clearwater.run_clearwater_live_test(
+ dns_ip=dns_ip,
+ public_domain=self.vnf['parameters']["zone"])
+ duration = time.time() - start_time
+ self.__logger.info(short_result)
+ self.details['test_vnf'] = dict(result=short_result,
+ duration=duration)
+ try:
+ vnf_test_rate = short_result['passed'] / (
+ short_result['total'] - short_result['skipped'])
+ # orchestrator + vnf + test_vnf
+ self.result += vnf_test_rate / 3 * 100
+ except ZeroDivisionError:
+ self.__logger.error("No test has been executed")
+ self.details['test_vnf'].update(status='FAIL')
+ return False
+ except Exception: # pylint: disable=broad-except
+ self.__logger.exception("Cannot calculate results")
+ self.details['test_vnf'].update(status='FAIL')
+ return False
+ return True if vnf_test_rate > 0 else False
+
+ def clean(self):
+ """Clean created objects/functions."""
+ assert self.cloud
+ try:
+ if self.stack:
+ self.cloud.delete_stack(self.stack.id, wait=True)
+ except Exception: # pylint: disable=broad-except
+ self.__logger.exception("Cannot clean stack ressources")
+ super(HeatIms, self).clean()
+ if self.role:
+ self.orig_cloud.delete_role(self.role.id)
+
+
+# ----------------------------------------------------------
+#
+# YAML UTILS
+#
+# -----------------------------------------------------------
+def get_config(parameter, file_path):
+ """
+ Get config parameter.
+
+ Returns the value of a given parameter in file.yaml
+ parameter must be given in string format with dots
+ Example: general.openstack.image_name
+ """
+ with open(file_path) as config_file:
+ file_yaml = yaml.safe_load(config_file)
+ config_file.close()
+ value = file_yaml
+ for element in parameter.split("."):
+ value = value.get(element)
+ if value is None:
+ raise ValueError("The parameter %s is not defined in"
+ " reporting.yaml" % parameter)
+ return value
diff --git a/functest/opnfv_tests/vnf/ims/heat_ims.yaml b/functest/opnfv_tests/vnf/ims/heat_ims.yaml
new file mode 100644
index 000000000..883c4dffe
--- /dev/null
+++ b/functest/opnfv_tests/vnf/ims/heat_ims.yaml
@@ -0,0 +1,22 @@
+---
+orchestrator:
+ name: heat
+ version: '4.0'
+vnf:
+ name: clearwater
+ version: '129'
+ descriptor:
+ file_name: /src/heat_vims/clearwater.yaml
+ name: clearwater-opnfv
+ version: '129'
+ inputs:
+ zone: clearwater.opnfv
+ dn_range_start: "6505550000"
+ dn_range_length: "1000"
+ bono_cluster_size: 1
+ sprout_cluster_size: 1
+ vellum_cluster_size: 1
+ dime_cluster_size: 1
+ homer_cluster_size: 1
+ dnssec_key:
+ GkBraPnditvP2Em4oXV5wUTawmZaGGuO+Jt3ZnFkznGV3zFoQ+Ak13nuuOnO0JV5FqAr/KitdW6siqjXSjROXg==
diff --git a/functest/tests/unit/vnf/ims/test_ims_base.py b/functest/tests/unit/vnf/ims/test_clearwater.py
index a3f7e2354..93f8ffe4a 100644
--- a/functest/tests/unit/vnf/ims/test_ims_base.py
+++ b/functest/tests/unit/vnf/ims/test_clearwater.py
@@ -12,15 +12,15 @@ import unittest
import mock
-from functest.opnfv_tests.vnf.ims import clearwater_ims_base as ims_base
+from functest.opnfv_tests.vnf.ims import clearwater
-class ClearwaterOnBoardingBaseTesting(unittest.TestCase):
+class ClearwaterTesting(unittest.TestCase):
def setUp(self):
with mock.patch('functest.opnfv_tests.vnf.ims.cloudify_ims.'
'os.makedirs'):
- self.ims_vnf = ims_base.ClearwaterOnBoardingBase("foo")
+ self.ims_vnf = clearwater.ClearwaterTesting("foo", "0.0.0.0")
self.mock_post = mock.Mock()
attrs = {'status_code': 201,