aboutsummaryrefslogtreecommitdiffstats
path: root/functest_kubernetes/ims/ims.py
diff options
context:
space:
mode:
authorCédric Ollivier <cedric.ollivier@orange.com>2020-03-12 17:31:56 +0100
committerCédric Ollivier <cedric.ollivier@orange.com>2020-03-13 10:48:50 +0100
commit080d2414682d5fecea8c01640e2e5971278fe19d (patch)
treeb6c165c9d2d0002c46e7f592f3f38bb6b53bd735 /functest_kubernetes/ims/ims.py
parentefee842caa2585c2174c9b780ea1d33f69c69f2e (diff)
Deploy Clearwater IMS using Kubernetes
The new testcase "k8s_vims" deploys and tests Clearwater IMS using Kubernetes. It follows the procedures proposed by clearwater-docker [1]. [1] https://github.com/Metaswitch/clearwater-docker Change-Id: I2fe3cd03a5dedfc61fbab294c53b4bc0b0fa70be Signed-off-by: Cédric Ollivier <cedric.ollivier@orange.com>
Diffstat (limited to 'functest_kubernetes/ims/ims.py')
-rw-r--r--functest_kubernetes/ims/ims.py187
1 files changed, 187 insertions, 0 deletions
diff --git a/functest_kubernetes/ims/ims.py b/functest_kubernetes/ims/ims.py
new file mode 100644
index 00000000..9a37a021
--- /dev/null
+++ b/functest_kubernetes/ims/ims.py
@@ -0,0 +1,187 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2020 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
+
+"""Deploy and Test Clearwater vIMS using Kubernetes"""
+
+import logging
+import time
+import re
+import yaml
+
+from kubernetes import client
+from kubernetes import config
+from kubernetes import watch
+import pkg_resources
+
+from xtesting.core import testcase
+
+
+class Vims(testcase.TestCase):
+ """Deploy and Test Clearwater vIMS using Kubernetes
+
+ It leverage on the Python kubernetes client to apply operation proposed by
+ clearwater-docker.
+
+ See https://github.com/Metaswitch/clearwater-docker for more details
+ """
+ namespace = 'default'
+ zone = 'default.svc.cluster.local'
+ watch_timeout = 1200
+ metadata_name = "env-vars"
+ test_image_name = "ollivier/clearwater-live-test:latest"
+ test_container_name = "live-test"
+
+ __logger = logging.getLogger(__name__)
+
+ deployment_list = [
+ "astaire", "bono", "cassandra", "chronos", "ellis", "etcd", "homer",
+ "homestead", "homestead-prov", "ralf", "sprout"]
+
+ def __init__(self, **kwargs):
+ super(Vims, self).__init__(**kwargs)
+ config.load_kube_config()
+ self.corev1 = client.CoreV1Api()
+ self.appsv1 = client.AppsV1Api()
+
+ def deploy_vnf(self):
+ """Deploy vIMS as proposed by clearwater-docker
+
+ It leverages on unofficial Clearwater dockers as proposed in the
+ documentation.
+
+ See https://github.com/Metaswitch/clearwater-docker for more details
+ """
+ metadata = client.V1ObjectMeta(
+ name=self.metadata_name, namespace=self.namespace)
+ body = client.V1ConfigMap(
+ metadata=metadata,
+ data={"ADDITIONAL_SHARED_CONFIG": "", "ZONE": self.zone})
+ api_response = self.corev1.create_namespaced_config_map(
+ self.namespace, body=body)
+ self.__logger.debug("create_namespaced_config_map: %s", api_response)
+ for deployment in self.deployment_list:
+ with open(pkg_resources.resource_filename(
+ 'functest_kubernetes',
+ 'ims/{}-depl.yaml'.format(deployment))) as yfile:
+ body = yaml.safe_load(yfile)
+ resp = self.appsv1.create_namespaced_deployment(
+ body=body, namespace="default")
+ self.__logger.info("Deployment %s created", resp.metadata.name)
+ self.__logger.debug(
+ "create_namespaced_deployment: %s", api_response)
+ for service in self.deployment_list:
+ with open(pkg_resources.resource_filename(
+ 'functest_kubernetes',
+ 'ims/{}-svc.yaml'.format(service))) as yfile:
+ body = yaml.safe_load(yfile)
+ resp = self.corev1.create_namespaced_service(
+ body=body, namespace="default")
+ self.__logger.info("Service %s created", resp.metadata.name)
+ self.__logger.debug(
+ "create_namespaced_service: %s", api_response)
+ status = self.deployment_list.copy()
+ watch_deployment = watch.Watch()
+ for event in watch_deployment.stream(
+ func=self.appsv1.list_namespaced_deployment,
+ namespace=self.namespace, timeout_seconds=self.watch_timeout):
+ if event["object"].status.ready_replicas == 1:
+ if event['object'].metadata.name in status:
+ status.remove(event['object'].metadata.name)
+ self.__logger.info(
+ "%s started in %0.2f sec",
+ event['object'].metadata.name,
+ time.time()-self.start_time)
+ if len(status) == 0:
+ watch_deployment.stop()
+ self.result = 1/2 * 100
+
+ def test_vnf(self):
+ """Test vIMS as proposed by clearwater-live-test
+
+ It leverages on an unofficial Clearwater docker to allow testing from
+ the Kubernetes cluster.
+
+ See https://github.com/Metaswitch/clearwater-live-test for more details
+ """
+ container = client.V1Container(
+ name=self.test_container_name, image=self.test_image_name)
+ spec = client.V1PodSpec(containers=[container], restart_policy="Never")
+ metadata = client.V1ObjectMeta(name=self.test_container_name)
+ body = client.V1Pod(metadata=metadata, spec=spec)
+ api_response = self.corev1.create_namespaced_pod(self.namespace, body)
+ watch_deployment = watch.Watch()
+ for event in watch_deployment.stream(
+ func=self.corev1.list_namespaced_pod,
+ namespace=self.namespace, timeout_seconds=self.watch_timeout):
+ if event["object"].metadata.name == self.test_container_name:
+ if (event["object"].status.phase == 'Succeeded'
+ or event["object"].status.phase == 'Error'):
+ watch_deployment.stop()
+ api_response = self.corev1.read_namespaced_pod_log(
+ name=self.test_container_name, namespace=self.namespace)
+ self.__logger.info(api_response)
+ vims_test_result = {}
+ try:
+ grp = re.search(
+ r'^(\d+) failures out of (\d+) tests run.*\n'
+ r'(\d+) tests skipped$', api_response,
+ re.MULTILINE | re.DOTALL)
+ assert grp
+ vims_test_result["failures"] = int(grp.group(1))
+ vims_test_result["total"] = int(grp.group(2))
+ vims_test_result["skipped"] = int(grp.group(3))
+ vims_test_result['passed'] = (
+ int(grp.group(2)) - int(grp.group(3)) - int(grp.group(1)))
+ if vims_test_result['total'] - vims_test_result['skipped'] > 0:
+ vnf_test_rate = vims_test_result['passed'] / (
+ vims_test_result['total'] - vims_test_result['skipped'])
+ else:
+ vnf_test_rate = 0
+ self.result += 1/2 * 100 * vnf_test_rate
+ except Exception: # pylint: disable=broad-except
+ self.__logger.exception("Cannot parse live tests results")
+
+ def run(self, **kwargs):
+ self.start_time = time.time()
+ try:
+ self.deploy_vnf()
+ self.test_vnf()
+ except client.rest.ApiException:
+ self.__logger.exception("Cannot deploy and test vIms")
+ self.stop_time = time.time()
+
+ def clean(self):
+ try:
+ api_response = self.corev1.delete_namespaced_config_map(
+ name=self.metadata_name, namespace=self.namespace)
+ self.__logger.debug(
+ "delete_namespaced_config_map: %s", api_response)
+ except client.rest.ApiException:
+ pass
+ try:
+ api_response = self.corev1.delete_namespaced_pod(
+ name=self.test_container_name, namespace=self.namespace)
+ self.__logger.debug("delete_namespaced_pod: %s", api_response)
+ except client.rest.ApiException:
+ pass
+ for deployment in self.deployment_list:
+ try:
+ api_response = self.appsv1.delete_namespaced_deployment(
+ name=deployment, namespace=self.namespace)
+ self.__logger.debug(
+ "delete_namespaced_deployment: %s", api_response)
+ except client.rest.ApiException:
+ pass
+ try:
+ api_response = self.corev1.delete_namespaced_service(
+ name=deployment, namespace=self.namespace)
+ self.__logger.debug(
+ "delete_namespaced_service: %s", api_response)
+ except client.rest.ApiException:
+ pass