summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorValentin Boucher <valentin.boucher@kontron.com>2018-07-19 11:35:50 -0400
committerCédric Ollivier <cedric.ollivier@orange.com>2018-07-23 22:17:34 +0200
commit026a9bfaa656d0e5ade327feda64f17796d6f209 (patch)
tree83e722c0c39885ba3355e86185fde2b698a4b076
parentc5b8affdabf4de9f758d0ba47547aa78fb004801 (diff)
New Heat IMS testcase
In order to validate OpenStack Master deployment we create this new testcase using OpenStack Heat as an Orchestrator for Clearwater VNF JIRA: FUNCTEST-995 Change-Id: I8b7b74a3753c2d4d4614e9a2798283bd3f99d5d2 Signed-off-by: Valentin Boucher <valentin.boucher@kontron.com>
-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/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
11 files changed, 447 insertions, 107 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/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,