From c0ae71815239fb8abdb9824f6a52cd2d3d013c06 Mon Sep 17 00:00:00 2001 From: Lionel Jouin Date: Mon, 24 Oct 2022 17:28:37 +0200 Subject: [PATCH 1/1] Meridio: e2e tests on Kind with Helm Run the Meridio e2e tests on Kind with specific Kubernetes, NSM, TAPA, Meridio Version and specifc IP Family. The tests are using the helm chart (without the operator). Once done, badges report the sucesses and failures Change-Id: Ic8630aaca493bf3e6bf812d19457a8df0fe7108f --- jjb/nsm/e2e.Jenkinsfile | 223 +++++++++++++++++++++++++++++ jjb/nsm/meridio-e2e-test-kind.yaml | 86 +++++++++++ 2 files changed, 309 insertions(+) create mode 100644 jjb/nsm/e2e.Jenkinsfile create mode 100644 jjb/nsm/meridio-e2e-test-kind.yaml diff --git a/jjb/nsm/e2e.Jenkinsfile b/jjb/nsm/e2e.Jenkinsfile new file mode 100644 index 00000000..6eed926d --- /dev/null +++ b/jjb/nsm/e2e.Jenkinsfile @@ -0,0 +1,223 @@ +import org.jenkinsci.plugins.pipeline.modeldefinition.Utils + +node('nordix-nsm-build-ubuntu1804') { + build_number = env.BUILD_NUMBER + workspace = env.WORKSPACE + ws("${workspace}/${build_number}") { + def git_project = params.GIT_PROJECT + def current_branch = params.CURRENT_BRANCH + def default_branch = params.DEFAULT_BRANCH + def next = params.NEXT + + def meridio_version = params.MERIDIO_VERSION + def tapa_version = params.TAPA_VERSION + def kubernetes_version = params.KUBERNETES_VERSION + def nsm_version = params.NSM_VERSION + def ip_family = params.IP_FAMILY + + stage('Clone/Checkout') { + git branch: default_branch, url: git_project + checkout([ + $class: 'GitSCM', + branches: [[name: current_branch]], + extensions: [], + userRemoteConfigs: [[ + refspec: '+refs/pull/*/head:refs/remotes/origin/pr/*', + url: git_project + ]] + ]) + sh 'git show' + } + timeout(60) { + stage('Environment') { + currentBuild.description = "Meridio version: $meridio_version / TAPA version: $tapa_version / NSM version: $nsm_version / IP Family: $ip_family / Kubernetes version: $kubernetes_version / Current Branch: $current_branch" + + ExecSh("make -s -C docs/demo/scripts/kind/ KUBERNETES_VERSION=$kubernetes_version NSM_VERSION=$nsm_version KUBERNETES_IP_FAMILY=$ip_family").call() + ExecSh("helm install deployments/helm/ --generate-name --create-namespace --namespace red --set trench.name=trench-a --set ipFamily=$ip_family").call() + ExecSh("helm install deployments/helm/ --generate-name --create-namespace --namespace red --set trench.name=trench-b --set vlan.id=200 --set ipFamily=$ip_family").call() + ExecSh('helm install examples/target/helm/ --generate-name --create-namespace --namespace red --set applicationName=target-a --set default.trench.name=trench-a').call() + ExecSh('helm install examples/target/helm/ --generate-name --create-namespace --namespace red --set applicationName=target-b --set default.trench.name=trench-b').call() + sh 'sleep 10' + ExecSh('kubectl wait --for=condition=Ready pods --all --all-namespaces --timeout=5m').call() + } + stage('E2E') { + echo "Meridio version: $meridio_version" + echo "TAPA version: $tapa_version" + ExecSh("make e2e E2E_PARAMETERS=\"\$(cat ./test/e2e/environment/kind-helm/$ip_family/config.txt | tr '\\n' ' ')\"").call() + } + } + stage('Cleanup') { + Cleanup() + } + stage('Report') { + Report().call() + } + stage('Next') { + Next(next).call() + } + } +} + +def Next(next) { + if (next == 'true') { + return { + def meridio_version = GetMeridioVersion() + def tapa_version = GetTAPAVersion() + def nsm_version = GetNSMVersion() + def kubernetes_version = GetKubernetesVersion() + def ip_family = GetIPFamily() + echo "Meridio version: $meridio_version / TAPA version: $tapa_version / NSM version: $nsm_version / IP Family: $ip_family / Kubernetes version: $kubernetes_version" + build job: 'meridio-e2e-test-kind', parameters: [ + string(name: 'NEXT', value: 'true'), + string(name: 'MERIDIO_VERSION', value: "$meridio_version"), + string(name: 'TAPA_VERSION', value: "$tapa_version"), + string(name: 'KUBERNETES_VERSION', value: "$kubernetes_version"), + string(name: 'NSM_VERSION', value: "$nsm_version"), + string(name: 'IP_FAMILY', value: "$ip_family") + ], wait: false + } + } else { + return { + Utils.markStageSkippedForConditional('Next') + } + } +} + +def GetMeridioVersion() { + def number_of_versions = sh(script: 'cat test/e2e/environment/kind-helm/test-scope.yaml | yq ".Meridio[]" | wc -l', returnStdout: true).trim() + def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim() + def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim() + return sh(script: "cat test/e2e/environment/kind-helm/test-scope.yaml | yq '.Meridio[$index_of_version]'", returnStdout: true).trim() +} + +def GetTAPAVersion() { + def number_of_versions = sh(script: 'cat test/e2e/environment/kind-helm/test-scope.yaml | yq ".TAPA[]" | wc -l', returnStdout: true).trim() + def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim() + def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim() + return sh(script: "cat test/e2e/environment/kind-helm/test-scope.yaml | yq '.TAPA[$index_of_version]'", returnStdout: true).trim() +} + +def GetNSMVersion() { + def number_of_versions = sh(script: 'cat test/e2e/environment/kind-helm/test-scope.yaml | yq ".NSM[]" | wc -l', returnStdout: true).trim() + def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim() + def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim() + return sh(script: "cat test/e2e/environment/kind-helm/test-scope.yaml | yq '.NSM[$index_of_version]'", returnStdout: true).trim() +} + +def GetKubernetesVersion() { + def number_of_versions = sh(script: 'cat test/e2e/environment/kind-helm/test-scope.yaml | yq ".Kubernetes[]" | wc -l', returnStdout: true).trim() + def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim() + def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim() + return sh(script: "cat test/e2e/environment/kind-helm/test-scope.yaml | yq '.Kubernetes[$index_of_version]'", returnStdout: true).trim() +} + +def GetIPFamily() { + def number_of_ip_family = sh(script: 'cat test/e2e/environment/kind-helm/test-scope.yaml | yq ".IP-Family[]" | wc -l', returnStdout: true).trim() + def index_of_ip_family_temp = sh(script: "shuf -i 1-$number_of_ip_family -n1", returnStdout: true).trim() + def index_of_ip_family = sh(script: "expr $index_of_ip_family_temp - 1 || true", returnStdout: true).trim() + return sh(script: "cat test/e2e/environment/kind-helm/test-scope.yaml | yq '.IP-Family[$index_of_ip_family]'", returnStdout: true).trim() +} + +// http://JENKINS_URL/job/meridio-e2e-test-kind/api/json?tree=allBuilds[status,timestamp,id,result,description]{0,9}&pretty=true +def Report() { + return { + def jenkins_url = 'jenkins.nordix.org' + + def success = sh(script: """ + data=\$(curl -s -L "http://$jenkins_url/job/meridio-e2e-test-kind/api/json?tree=allBuilds\\[status,timestamp,id,result,description\\]\\{0,999\\}&pretty=true") + success=\$(echo \"\$data\" | jq -r '.allBuilds[] | select(.result == \"SUCCESS\") | [.description] | @tsv' | grep -v \"^\$\") + echo \$success + """, returnStdout: true).trim() + + def failure = sh(script: """ + data=\$(curl -s -L "http://$jenkins_url/job/meridio-e2e-test-kind/api/json?tree=allBuilds\\[status,timestamp,id,result,description\\]\\{0,999\\}&pretty=true") + failure=\$(echo \"\$data\" | jq -r '.allBuilds[] | select(.result == \"FAILURE\") | [.description] | @tsv' | grep -v \"^\$\") + echo \$failure + """, returnStdout: true).trim() + + ReportMeridio(success, failure).call() + ReportTAPA(success, failure).call() + ReportNSM(success, failure).call() + ReportIPFamily(success, failure).call() + ReportKubernetes(success, failure).call() + } +} + +def ReportMeridio(success, failure) { + return { + def meridio_success = sh(script: "echo \"$success\" | grep -oP '(?<=Meridio version: ).*?(?=\\/)' | sort | uniq -c | awk '{ printf \"%s %s 0\\n\", \$2, \$1 }'", returnStdout: true).trim() + def meridio_failure = sh(script: "echo \"$failure\" | grep -oP '(?<=Meridio version: ).*?(?=\\/)' | sort | uniq -c | awk '{ printf \"%s 0 %s\\n\", \$2, \$1 }'", returnStdout: true).trim() + def meridio = sh(script: "echo \"$meridio_success\\n$meridio_failure\" | awk '{ success[\$1] += \$2 ; failure[\$1] += \$3 } END { for(elem in success) print elem, success[elem], failure[elem] }' | sort -k1", returnStdout: true).trim() + def formatted = sh(script: "echo \"$meridio\" | awk '{ printf \"%s (✅ %s / ❌ %s)\\n\", \$1, \$2, \$3 }' | sed ':a;N;\$!ba;s/\\n/ | /g'", returnStdout: true).trim() + echo "Meridio: $formatted" + def meridio_badge = addEmbeddableBadgeConfiguration(id: 'meridio-e2e-kind-meridio', subject: 'Meridio', color: '#0B1F67', status: "$formatted") + } +} + +def ReportTAPA(success, failure) { + return { + def tapa_success = sh(script: "echo \"$success\" | grep -oP '(?<=TAPA version: ).*?(?=\\/)' | sort | uniq -c | awk '{ printf \"%s %s 0\\n\", \$2, \$1 }'", returnStdout: true).trim() + def tapa_failure = sh(script: "echo \"$failure\" | grep -oP '(?<=TAPA version: ).*?(?=\\/)' | sort | uniq -c | awk '{ printf \"%s 0 %s\\n\", \$2, \$1 }'", returnStdout: true).trim() + def tapa = sh(script: "echo \"$tapa_success\\n$tapa_failure\" | awk '{ success[\$1] += \$2 ; failure[\$1] += \$3 } END { for(elem in success) print elem, success[elem], failure[elem] }' | sort -k1", returnStdout: true).trim() + def formatted = sh(script: "echo \"$tapa\" | awk '{ printf \"%s (✅ %s / ❌ %s)\\n\", \$1, \$2, \$3 }' | sed ':a;N;\$!ba;s/\\n/ | /g'", returnStdout: true).trim() + echo "TAPA: $formatted" + def tapa_badge = addEmbeddableBadgeConfiguration(id: 'meridio-e2e-kind-tapa', subject: 'TAPA', color: '#0B1F67', status: "$formatted") + } +} + +def ReportNSM(success, failure) { + return { + def nsm_success = sh(script: "echo \"$success\" | grep -oP '(?<=NSM version: ).*?(?=\\/)' | sort | uniq -c | awk '{ printf \"%s %s 0\\n\", \$2, \$1 }'", returnStdout: true).trim() + def nsm_failure = sh(script: "echo \"$failure\" | grep -oP '(?<=NSM version: ).*?(?=\\/)' | sort | uniq -c | awk '{ printf \"%s 0 %s\\n\", \$2, \$1 }'", returnStdout: true).trim() + def nsm = sh(script: "echo \"$nsm_success\\n$nsm_failure\" | awk '{ success[\$1] += \$2 ; failure[\$1] += \$3 } END { for(elem in success) print elem, success[elem], failure[elem] }' | sort -k1", returnStdout: true).trim() + def formatted = sh(script: "echo \"$nsm\" | awk '{ printf \"%s (✅ %s / ❌ %s)\\n\", \$1, \$2, \$3 }' | sed ':a;N;\$!ba;s/\\n/ | /g'", returnStdout: true).trim() + echo "NSM: $formatted" + def nsm_badge = addEmbeddableBadgeConfiguration(id: 'meridio-e2e-kind-nsm', subject: 'NSM', color: '#0B1F67', status: "$formatted") + } +} + +def ReportIPFamily(success, failure) { + return { + def ip_family_success = sh(script: "echo \"$success\" | grep -oP '(?<=IP Family: ).*?(?=\\/)' | sort | uniq -c | awk '{ printf \"%s %s 0\\n\", \$2, \$1 }'", returnStdout: true).trim() + def ip_family_failure = sh(script: "echo \"$failure\" | grep -oP '(?<=IP Family: ).*?(?=\\/)' | sort | uniq -c | awk '{ printf \"%s 0 %s\\n\", \$2, \$1 }'", returnStdout: true).trim() + def ip_family = sh(script: "echo \"$ip_family_success\\n$ip_family_failure\" | awk '{ success[\$1] += \$2 ; failure[\$1] += \$3 } END { for(elem in success) print elem, success[elem], failure[elem] }' | sort -k1", returnStdout: true).trim() + def formatted = sh(script: "echo \"$ip_family\" | awk '{ printf \"%s (✅ %s / ❌ %s)\\n\", \$1, \$2, \$3 }' | sed ':a;N;\$!ba;s/\\n/ | /g'", returnStdout: true).trim() + echo "IP Family: $formatted" + def ip_family_badge = addEmbeddableBadgeConfiguration(id: 'meridio-e2e-kind-ip-family', subject: 'IP Family', color: '#0B1F67', status: "$formatted") + } +} + +def ReportKubernetes(success, failure) { + return { + def kubernetes_success = sh(script: "echo \"$success\" | grep -oP '(?<=Kubernetes version: ).*?(?=\\/)' | sort | uniq -c | awk '{ printf \"%s %s 0\\n\", \$2, \$1 }'", returnStdout: true).trim() + def kubernetes_failure = sh(script: "echo \"$failure\" | grep -oP '(?<=Kubernetes version: ).*?(?=\\/)' | sort | uniq -c | awk '{ printf \"%s 0 %s\\n\", \$2, \$1 }'", returnStdout: true).trim() + def kubernetes = sh(script: "echo \"$kubernetes_success\\n$kubernetes_failure\" | awk '{ success[\$1] += \$2 ; failure[\$1] += \$3 } END { for(elem in success) print elem, success[elem], failure[elem] }' | sort -k1", returnStdout: true).trim() + def formatted = sh(script: "echo \"$kubernetes\" | awk '{ printf \"%s (✅ %s / ❌ %s)\\n\", \$1, \$2, \$3 }' | sed ':a;N;\$!ba;s/\\n/ | /g'", returnStdout: true).trim() + echo "Kubernetes: $formatted" + def kubernetes_badge = addEmbeddableBadgeConfiguration(id: 'meridio-e2e-kind-kubernetes', subject: 'Kubernetes', color: '#0B1F67', status: "$formatted") + } +} + +// Raise error in Jenkins job +def Error(e) { + return { + Cleanup() + error e + } +} + +// Cleanup directory and kind cluster +def Cleanup() { + ExecSh('make -s -C docs/demo/scripts/kind/ clean').call() + cleanWs() +} + +// Execute command +def ExecSh(command) { + return { + sh """ + . \${HOME}/.profile + ${command} + """ + } +} diff --git a/jjb/nsm/meridio-e2e-test-kind.yaml b/jjb/nsm/meridio-e2e-test-kind.yaml new file mode 100644 index 00000000..3a60492d --- /dev/null +++ b/jjb/nsm/meridio-e2e-test-kind.yaml @@ -0,0 +1,86 @@ +--- +# ============LICENSE_START======================================================= +# Copyright (C) 2021 Nordix Foundation. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# ============LICENSE_END========================================================= + +- project: + name: 'meridio-e2e-test-kind' + + project: 'meridio-e2e-test-kind' + + jobs: + - 'meridio-e2e-test-kind' + +- job-template: + name: 'meridio-e2e-test-kind' + project-type: pipeline + disabled: '{obj:disabled}' + + concurrent: false + + properties: + - github: + url: https://github.com/Nordix/Meridio-Operator + + parameters: + - string: + name: GITHUB_ORGANIZATION + default: 'Nordix' + description: GitHub Organization + - string: + name: PROJECT + default: 'Meridio' + description: GitHub project + - string: + name: GIT_PROJECT + default: "https://github.com/$GITHUB_ORGANIZATION/$PROJECT.git" + description: Git URL of the project + - string: + name: CURRENT_BRANCH + default: "master" + description: Current Git branch + - string: + name: DEFAULT_BRANCH + default: "master" + description: default branch + - string: + name: NEXT + default: 'false' + description: Does the job run has to call for a next run? + - string: + name: MERIDIO_VERSION + default: 'latest' + description: Version of Meridio + - string: + name: TAPA_VERSION + default: 'latest' + description: Version of Meridio TAPA + - string: + name: KUBERNETES_VERSION + default: 'v1.25' + description: Version of Kubernetes + - string: + name: NSM_VERSION + default: 'v1.6.0' + description: Version of NSM + - string: + name: IP_FAMILY + default: 'dualstack' + description: IP Family + + dsl: + !include-raw-escape: e2e.Jenkinsfile -- 2.25.1