aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ansible/site.yml1
-rw-r--r--docker/cnf/Dockerfile15
-rw-r--r--docker/cnf/testcases.yaml13
-rw-r--r--functest_kubernetes/cnf_conformance/__init__.py0
-rw-r--r--functest_kubernetes/cnf_conformance/conformance.py104
-rw-r--r--setup.cfg1
6 files changed, 134 insertions, 0 deletions
diff --git a/ansible/site.yml b/ansible/site.yml
index c8c8207c..e625a6ab 100644
--- a/ansible/site.yml
+++ b/ansible/site.yml
@@ -58,4 +58,5 @@
- xrally_kubernetes_full
- container: functest-kubernetes-cnf
tests:
+ - cnf_conformance
- k8s_vims
diff --git a/docker/cnf/Dockerfile b/docker/cnf/Dockerfile
index a01f4425..0100593a 100644
--- a/docker/cnf/Dockerfile
+++ b/docker/cnf/Dockerfile
@@ -1,4 +1,19 @@
FROM opnfv/functest-kubernetes-core:kali
+ARG CNF_CONFORMANCE_TAG=v0.7.2-beta1
+
+RUN apk --no-cache add --update wget curl libc6-compat && \
+ K8S_TAG=$(curl -s https://storage.googleapis.com/kubernetes-release/release/latest-1.19.txt) && \
+ case $(uname -m) in armv7l) ARCH=arm;; aarch64) ARCH=arm64;; x86_64) ARCH=amd64;; esac && \
+ curl https://storage.googleapis.com/kubernetes-release/release/$K8S_TAG/bin/linux/$ARCH/kubectl \
+ -s --output /usr/local/bin/kubectl && \
+ curl https://github.com/cncf/cnf-conformance/releases/download/$CNF_CONFORMANCE_TAG/cnf-conformance-$(echo $CNF_CONFORMANCE_TAG |cut -d\- -f 1)-$ARCH-static \
+ -Ls --output /usr/local/bin/cnf-conformance && \
+ chmod +x /usr/local/bin/kubectl /usr/local/bin/cnf-conformance && \
+ mkdir -p /src/cnf-conformance && \
+ curl -Ls https://raw.githubusercontent.com/cncf/cnf-conformance/$CNF_CONFORMANCE_TAG/example-cnfs/coredns/cnf-conformance.yml \
+ -s --output /src/cnf-conformance/cnf-conformance.yml && \
+ curl -Ls https://raw.githubusercontent.com/cncf/cnf-conformance/$CNF_CONFORMANCE_TAG/points.yml \
+ -s --output /src/cnf-conformance/points.yml
COPY testcases.yaml /usr/lib/python3.8/site-packages/xtesting/ci/testcases.yaml
CMD ["run_tests", "-t", "all"]
diff --git a/docker/cnf/testcases.yaml b/docker/cnf/testcases.yaml
index 68d1788d..e0d8bcb2 100644
--- a/docker/cnf/testcases.yaml
+++ b/docker/cnf/testcases.yaml
@@ -7,6 +7,19 @@ tiers:
Collection of VNF test cases.
testcases:
-
+ case_name: cnf_conformance
+ project_name: functest
+ criteria: 90
+ blocking: false
+ description: >-
+ Enable interoperability of Cloud native Network
+ Functions (CNFs) as proposed by
+ https://github.com/cncf/cnf-conformance
+ dependencies:
+ - DEPLOY_SCENARIO: 'k8-*'
+ run:
+ name: cnf_conformance
+ -
case_name: k8s_vims
project_name: functest
criteria: 100
diff --git a/functest_kubernetes/cnf_conformance/__init__.py b/functest_kubernetes/cnf_conformance/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/functest_kubernetes/cnf_conformance/__init__.py
diff --git a/functest_kubernetes/cnf_conformance/conformance.py b/functest_kubernetes/cnf_conformance/conformance.py
new file mode 100644
index 00000000..1f80f15c
--- /dev/null
+++ b/functest_kubernetes/cnf_conformance/conformance.py
@@ -0,0 +1,104 @@
+#!/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
+
+"""
+The CNF Conformance program enables interoperability of Cloud native Network
+Functions (CNFs) from multiple vendors running on top of Kubernetes supplied by
+different vendors [1].
+[1] https://github.com/cncf/cnf-conformance
+"""
+
+from __future__ import division
+
+import fnmatch
+import logging
+import os
+import re
+import shutil
+import subprocess
+import time
+import yaml
+
+import prettytable
+
+from xtesting.core import testcase
+
+
+class CNFConformance(testcase.TestCase):
+ """ Implement CNF Conformance driver.
+
+ https://hackmd.io/@vulk/SkY54QnsU
+ """
+
+ src_dir = '/src/cnf-conformance'
+ bin_dir = '/usr/local/bin'
+ default_tag = 'all'
+
+ __logger = logging.getLogger(__name__)
+
+ def setup(self):
+ """Implement initialization and pre-reqs steps"""
+ os.makedirs(self.res_dir, exist_ok=True)
+
+ shutil.copy2(os.path.join(self.src_dir, 'points.yml'), self.res_dir)
+ shutil.copy2(
+ os.path.join(self.src_dir, 'cnf-conformance.yml'), self.res_dir)
+ os.chdir(self.res_dir)
+ # cnf-conformance must be in the working dir
+ # https://github.com/cncf/cnf-conformance/issues/388
+ if not os.path.exists(os.path.join(self.res_dir, 'cnf-conformance')):
+ os.symlink(
+ os.path.join(self.bin_dir, 'cnf-conformance'),
+ os.path.join(self.res_dir, 'cnf-conformance'))
+ cmd = ['cnf-conformance', 'setup']
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ self.__logger.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
+ cmd = ['cnf-conformance', 'cnf_setup',
+ 'cnf-config=cnf-conformance.yml']
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ self.__logger.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
+
+ def run_conformance(self, **kwargs):
+ """Run CNF Conformance"""
+ # a previous results.yml leads to interactive mode
+ if os.path.exists(os.path.join(self.res_dir, 'results.yml')):
+ os.remove(os.path.join(self.res_dir, 'results.yml'))
+ cmd = ['cnf-conformance', kwargs.get("tag", self.default_tag)]
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ self.__logger.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
+ for lfile in os.listdir(self.res_dir):
+ if fnmatch.fnmatch(lfile, 'cnf-conformance-results-*.yml'):
+ with open(os.path.join(self.res_dir, lfile)) as yfile:
+ self.details = yaml.safe_load(yfile)
+ msg = prettytable.PrettyTable(
+ header_style='upper', padding_width=5,
+ field_names=['name', 'status'])
+ for item in self.details['items']:
+ msg.add_row([item['name'], item['status']])
+ self.__logger.info("\n\n%s\n", msg.get_string())
+ grp = re.search(r'Final score: (\d+) of (\d+)', output.decode("utf-8"))
+ if grp:
+ self.result = int(grp.group(1)) / int(grp.group(2)) * 100
+
+ def run(self, **kwargs):
+ """"Running the test with example CNF"""
+ self.start_time = time.time()
+ try:
+ self.setup()
+ self.run_conformance(**kwargs)
+ except Exception: # pylint: disable=broad-except
+ self.__logger.exception("Can not run CNF Conformance")
+ self.stop_time = time.time()
+
+ def clean(self):
+ cmd = ['cnf-conformance', 'cnf_cleanup',
+ 'cnf-config=cnf-conformance.yml']
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ self.__logger.info("%s\n%s", " ".join(cmd), output.decode("utf-8"))
+ shutil.rmtree(self.res_dir)
diff --git a/setup.cfg b/setup.cfg
index bfb45a65..bcc0791f 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -13,3 +13,4 @@ xtesting.testcase =
k8s_vims = functest_kubernetes.ims.ims:Vims
kube_hunter = functest_kubernetes.security.security:KubeHunter
kube_bench = functest_kubernetes.security.security:KubeBench
+ cnf_conformance = functest_kubernetes.cnf_conformance.conformance:CNFConformance