2 Copyright (c) 2022 Nordix Foundation
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
16 import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
18 node('nordix-nsm-build-ubuntu2204') {
19 build_number = env.BUILD_NUMBER
20 workspace = env.WORKSPACE
21 ws("${workspace}/${build_number}") {
22 def git_project = params.GIT_PROJECT
23 def current_branch = params.CURRENT_BRANCH
24 def default_branch = params.DEFAULT_BRANCH
25 def next = params.NEXT
27 def meridio_version = params.MERIDIO_VERSION
28 def tapa_version = params.TAPA_VERSION
29 def kubernetes_version = params.KUBERNETES_VERSION
30 def nsm_version = params.NSM_VERSION
31 def ip_family = params.IP_FAMILY
32 def number_of_workers = params.NUMBER_OF_WORKERS
33 def environment_name = params.ENVIRONMENT_NAME
34 def focus = params.FOCUS
35 def skip = params.SKIP
36 def kind_external_host_default_route = params.KIND_EXTERNAL_HOST_DEFAULT_ROUTE
38 def seed = params.SEED
40 stage('Clone/Checkout') {
41 git branch: default_branch, url: git_project
44 branches: [[name: current_branch]],
47 refspec: '+refs/pull/*/head:refs/remotes/origin/pr/*',
54 stage('Environment') {
55 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 / Seed: $seed"
57 def command = "make -s -C test/e2e/environment/$environment_name/ KUBERNETES_VERSION=$kubernetes_version NSM_VERSION=$nsm_version IP_FAMILY=$ip_family KUBERNETES_WORKERS=$number_of_workers MERIDIO_VERSION=$meridio_version TAPA_VERSION=$tapa_version KIND_EXTERNAL_HOST_DEFAULT_ROUTE=$kind_external_host_default_route"
59 ExecSh(command).call()
60 } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
61 currentBuild.result = 'ABORTED'
62 } catch (Exception e) {
63 unstable 'Environment setup failed'
64 currentBuild.result = 'FAILURE'
68 if (currentBuild.result != 'FAILURE' && currentBuild.result != 'ABORTED') {
69 def command = "make e2e E2E_PARAMETERS=\"\$(cat ./test/e2e/environment/$environment_name/$ip_family/config.txt | tr '\\n' ' ')\" E2E_SEED=$seed E2E_FOCUS=\"$focus\" E2E_SKIP=\"$skip\""
71 ExecSh(command).call()
72 currentBuild.result = 'SUCCESS'
73 } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
74 currentBuild.result = 'ABORTED'
75 } catch (Exception e) {
76 unstable 'E2E Tests failed'
77 currentBuild.result = 'FAILURE'
80 Utils.markStageSkippedForConditional('E2E')
86 Report(build_number).call()
87 } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
88 currentBuild.result = 'ABORTED'
89 } catch (Exception e) {
90 unstable 'Failed to create the report'
94 if (next == true && currentBuild.result != 'ABORTED') {
95 Next(next, number_of_workers, environment_name, focus, skip, current_branch).call()
97 Utils.markStageSkippedForConditional('Next')
106 def Next(next, number_of_workers, environment_name, focus, skip, current_branch) {
108 def meridio_version = GetMeridioVersion(environment_name)
109 def tapa_version = GetTAPAVersion(environment_name)
110 def nsm_version = GetNSMVersion(environment_name)
111 def kubernetes_version = GetKubernetesVersion(environment_name)
112 def ip_family = GetIPFamily(environment_name)
114 echo "Meridio version: $meridio_version / TAPA version: $tapa_version / NSM version: $nsm_version / IP Family: $ip_family / Kubernetes version: $kubernetes_version / Seed: $seed"
115 build job: 'meridio-e2e-test-kind', parameters: [
116 string(name: 'NEXT', value: 'true'),
117 string(name: 'MERIDIO_VERSION', value: "$meridio_version"),
118 string(name: 'TAPA_VERSION', value: "$tapa_version"),
119 string(name: 'KUBERNETES_VERSION', value: "$kubernetes_version"),
120 string(name: 'NSM_VERSION', value: "$nsm_version"),
121 string(name: 'IP_FAMILY', value: "$ip_family"),
122 string(name: 'NUMBER_OF_WORKERS', value: "$number_of_workers"),
123 string(name: 'ENVIRONMENT_NAME', value: "$environment_name"),
124 string(name: 'SEED', value: "$seed"),
125 string(name: 'FOCUS', value: "$focus"),
126 string(name: 'SKIP', value: "$skip"),
127 string(name: 'CURRENT_BRANCH', value: "$current_branch"),
128 string(name: 'DRY_RUN', value: env.DRY_RUN)
133 def GetMeridioVersion(environment_name) {
134 def number_of_versions = sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.Meridio[]' | wc -l", returnStdout: true).trim()
135 def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim()
136 def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim()
137 return sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.Meridio[$index_of_version]'", returnStdout: true).trim()
140 def GetTAPAVersion(environment_name) {
141 def number_of_versions = sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.TAPA[]' | wc -l", returnStdout: true).trim()
142 def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim()
143 def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim()
144 return sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.TAPA[$index_of_version]'", returnStdout: true).trim()
147 def GetNSMVersion(environment_name) {
148 def number_of_versions = sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.NSM[]' | wc -l", returnStdout: true).trim()
149 def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim()
150 def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim()
151 return sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.NSM[$index_of_version]'", returnStdout: true).trim()
154 def GetKubernetesVersion(environment_name) {
155 def number_of_versions = sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.Kubernetes[]' | wc -l", returnStdout: true).trim()
156 def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim()
157 def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim()
158 return sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.Kubernetes[$index_of_version]'", returnStdout: true).trim()
161 def GetIPFamily(environment_name) {
162 def number_of_ip_family = sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.IP-Family[]' | wc -l", returnStdout: true).trim()
163 def index_of_ip_family_temp = sh(script: "shuf -i 1-$number_of_ip_family -n1", returnStdout: true).trim()
164 def index_of_ip_family = sh(script: "expr $index_of_ip_family_temp - 1 || true", returnStdout: true).trim()
165 return sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.IP-Family[$index_of_ip_family]'", returnStdout: true).trim()
169 return sh(script: 'shuf -i 1-2147483647 -n1', returnStdout: true).trim()
172 // http://JENKINS_URL/job/meridio-e2e-test-kind/api/json?tree=allBuilds[status,timestamp,id,result,description]{0,9}&pretty=true
175 def jenkins_url = 'jenkins.nordix.org'
179 success = sh(script: """
180 data=\$(curl -s -L "http://$jenkins_url/job/meridio-e2e-test-kind/api/json?tree=allBuilds\\[status,timestamp,id,result,description\\]\\{0,1000\\}&pretty=true")
181 success=\$(echo \"\$data\" | jq -r '.allBuilds[] | select(.result == \"SUCCESS\") | [.description] | @tsv' | grep -v \"^\$\")
183 """, returnStdout: true).trim()
184 } catch (Exception e) {
189 failure = sh(script: """
190 data=\$(curl -s -L "http://$jenkins_url/job/meridio-e2e-test-kind/api/json?tree=allBuilds\\[status,timestamp,id,result,description\\]\\{0,1000\\}&pretty=true")
191 failure=\$(echo \"\$data\" | jq -r '.allBuilds[] | select(.result == \"FAILURE\") | [.description] | @tsv' | grep -v \"^\$\")
193 """, returnStdout: true).trim()
194 } catch (Exception e) {
197 ReportMeridio(success, failure).call()
198 ReportTAPA(success, failure).call()
199 ReportNSM(success, failure).call()
200 ReportIPFamily(success, failure).call()
201 ReportKubernetes(success, failure).call()
203 sh 'printenv > _output/parameters.txt'
204 sh "echo 'RESULT=$currentBuild.result' >> _output/parameters.txt"
207 archiveArtifacts artifacts: '_output/**/*.*', followSymlinks: false
208 sh "tar -czvf ${id}.tar.gz -C _output ."
209 withCredentials([string(credentialsId: 'nsm-nordix-artifactory-api-key', variable: 'API_KEY')]) {
210 sh "curl -H 'X-JFrog-Art-Api:${API_KEY}' -T ${id}.tar.gz 'https://artifactory.nordix.org/artifactory/cloud-native/meridio/e2e-test-reports/${id}.tar.gz'"
212 } catch (Exception e) {
217 def ReportMeridio(success, failure) {
219 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()
220 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()
221 def meridio = sh(script: "echo \"$meridio_success\\n$meridio_failure\" | grep -v '^\$' | awk '{ success[\$1] += \$2 ; failure[\$1] += \$3 } END { for(elem in success) print elem, success[elem], failure[elem] }' | sort -k1", returnStdout: true).trim()
222 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()
223 echo "Meridio: $formatted"
224 badge('meridio-e2e-kind-meridio', 'Meridio', formatted)
228 def ReportTAPA(success, failure) {
230 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()
231 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()
232 def tapa = sh(script: "echo \"$tapa_success\\n$tapa_failure\" | grep -v '^\$' | awk '{ success[\$1] += \$2 ; failure[\$1] += \$3 } END { for(elem in success) print elem, success[elem], failure[elem] }' | sort -k1", returnStdout: true).trim()
233 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()
234 echo "TAPA: $formatted"
235 badge('meridio-e2e-kind-tapa', 'TAPA', formatted)
239 def ReportNSM(success, failure) {
241 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()
242 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()
243 def nsm = sh(script: "echo \"$nsm_success\\n$nsm_failure\" | grep -v '^\$' | awk '{ success[\$1] += \$2 ; failure[\$1] += \$3 } END { for(elem in success) print elem, success[elem], failure[elem] }' | sort -k1", returnStdout: true).trim()
244 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()
245 echo "NSM: $formatted"
246 badge('meridio-e2e-kind-nsm', 'NSM', formatted)
250 def ReportIPFamily(success, failure) {
252 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()
253 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()
254 def ip_family = sh(script: "echo \"$ip_family_success\\n$ip_family_failure\" | grep -v '^\$' | awk '{ success[\$1] += \$2 ; failure[\$1] += \$3 } END { for(elem in success) print elem, success[elem], failure[elem] }' | sort -k1", returnStdout: true).trim()
255 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()
256 echo "IP Family: $formatted"
257 badge('meridio-e2e-kind-ip-family', 'IP Family', formatted)
261 def ReportKubernetes(success, failure) {
263 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()
264 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()
265 def kubernetes = sh(script: "echo \"$kubernetes_success\\n$kubernetes_failure\" | grep -v '^\$' | awk '{ success[\$1] += \$2 ; failure[\$1] += \$3 } END { for(elem in success) print elem, success[elem], failure[elem] }' | sort -k1", returnStdout: true).trim()
266 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()
267 echo "Kubernetes: $formatted"
268 badge('meridio-e2e-kind-kubernetes', 'Kubernetes', formatted)
272 def badge(id, subject, message) {
273 addEmbeddableBadgeConfiguration(id: "${id}", subject: "${subject}", color: '#0B1F67', status: "$message")
276 echo '{' >> _output/${id}.json
277 echo '"schemaVersion": 1,' >> _output/${id}.json
278 echo '"label": "${subject}",' >> _output/${id}.json
279 echo '"message": "${message}",' >> _output/${id}.json
280 echo '"color": "#0B1F67"' >> _output/${id}.json
281 echo '}' >> _output/${id}.json
285 // Raise error in Jenkins job
293 // Cleanup directory and kind cluster
295 def command = 'make -s -C docs/demo/scripts/kind/ clean'
296 ExecSh(command).call()
301 def ExecSh(command) {
303 if (env.DRY_RUN != 'true') {