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
37 def seed = params.SEED
39 stage('Clone/Checkout') {
40 git branch: default_branch, url: git_project
43 branches: [[name: current_branch]],
46 refspec: '+refs/pull/*/head:refs/remotes/origin/pr/*',
53 stage('Environment') {
54 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"
56 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"
58 ExecSh(command).call()
59 } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
60 currentBuild.result = 'ABORTED'
61 } catch (Exception e) {
62 unstable 'Environment setup failed'
63 currentBuild.result = 'FAILURE'
67 if (currentBuild.result != 'FAILURE' && currentBuild.result != 'ABORTED') {
68 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\""
70 ExecSh(command).call()
71 currentBuild.result = 'SUCCESS'
72 } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
73 currentBuild.result = 'ABORTED'
74 } catch (Exception e) {
75 unstable 'E2E Tests failed'
76 currentBuild.result = 'FAILURE'
79 Utils.markStageSkippedForConditional('E2E')
85 Report(build_number).call()
86 } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
87 currentBuild.result = 'ABORTED'
88 } catch (Exception e) {
89 unstable 'Failed to create the report'
93 if (next == true && currentBuild.result != 'ABORTED') {
94 Next(next, number_of_workers, environment_name, focus, skip, current_branch).call()
96 Utils.markStageSkippedForConditional('Next')
105 def Next(next, number_of_workers, environment_name, focus, skip, current_branch) {
107 def meridio_version = GetMeridioVersion(environment_name)
108 def tapa_version = GetTAPAVersion(environment_name)
109 def nsm_version = GetNSMVersion(environment_name)
110 def kubernetes_version = GetKubernetesVersion(environment_name)
111 def ip_family = GetIPFamily(environment_name)
113 echo "Meridio version: $meridio_version / TAPA version: $tapa_version / NSM version: $nsm_version / IP Family: $ip_family / Kubernetes version: $kubernetes_version / Seed: $seed"
114 build job: 'meridio-e2e-test-kind', parameters: [
115 string(name: 'NEXT', value: 'true'),
116 string(name: 'MERIDIO_VERSION', value: "$meridio_version"),
117 string(name: 'TAPA_VERSION', value: "$tapa_version"),
118 string(name: 'KUBERNETES_VERSION', value: "$kubernetes_version"),
119 string(name: 'NSM_VERSION', value: "$nsm_version"),
120 string(name: 'IP_FAMILY', value: "$ip_family"),
121 string(name: 'NUMBER_OF_WORKERS', value: "$number_of_workers"),
122 string(name: 'ENVIRONMENT_NAME', value: "$environment_name"),
123 string(name: 'SEED', value: "$seed"),
124 string(name: 'FOCUS', value: "$focus"),
125 string(name: 'SKIP', value: "$skip"),
126 string(name: 'CURRENT_BRANCH', value: "$current_branch"),
127 string(name: 'DRY_RUN', value: env.DRY_RUN)
132 def GetMeridioVersion(environment_name) {
133 def number_of_versions = sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.Meridio[]' | wc -l", returnStdout: true).trim()
134 def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim()
135 def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim()
136 return sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.Meridio[$index_of_version]'", returnStdout: true).trim()
139 def GetTAPAVersion(environment_name) {
140 def number_of_versions = sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.TAPA[]' | wc -l", returnStdout: true).trim()
141 def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim()
142 def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim()
143 return sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.TAPA[$index_of_version]'", returnStdout: true).trim()
146 def GetNSMVersion(environment_name) {
147 def number_of_versions = sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.NSM[]' | wc -l", returnStdout: true).trim()
148 def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim()
149 def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim()
150 return sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.NSM[$index_of_version]'", returnStdout: true).trim()
153 def GetKubernetesVersion(environment_name) {
154 def number_of_versions = sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.Kubernetes[]' | wc -l", returnStdout: true).trim()
155 def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim()
156 def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim()
157 return sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.Kubernetes[$index_of_version]'", returnStdout: true).trim()
160 def GetIPFamily(environment_name) {
161 def number_of_ip_family = sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.IP-Family[]' | wc -l", returnStdout: true).trim()
162 def index_of_ip_family_temp = sh(script: "shuf -i 1-$number_of_ip_family -n1", returnStdout: true).trim()
163 def index_of_ip_family = sh(script: "expr $index_of_ip_family_temp - 1 || true", returnStdout: true).trim()
164 return sh(script: "cat test/e2e/environment/$environment_name/test-scope.yaml | yq '.IP-Family[$index_of_ip_family]'", returnStdout: true).trim()
168 return sh(script: 'shuf -i 1-2147483647 -n1', returnStdout: true).trim()
171 // http://JENKINS_URL/job/meridio-e2e-test-kind/api/json?tree=allBuilds[status,timestamp,id,result,description]{0,9}&pretty=true
174 def jenkins_url = 'jenkins.nordix.org'
178 success = sh(script: """
179 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")
180 success=\$(echo \"\$data\" | jq -r '.allBuilds[] | select(.result == \"SUCCESS\") | [.description] | @tsv' | grep -v \"^\$\")
182 """, returnStdout: true).trim()
183 } catch (Exception e) {
188 failure = sh(script: """
189 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")
190 failure=\$(echo \"\$data\" | jq -r '.allBuilds[] | select(.result == \"FAILURE\") | [.description] | @tsv' | grep -v \"^\$\")
192 """, returnStdout: true).trim()
193 } catch (Exception e) {
196 ReportMeridio(success, failure).call()
197 ReportTAPA(success, failure).call()
198 ReportNSM(success, failure).call()
199 ReportIPFamily(success, failure).call()
200 ReportKubernetes(success, failure).call()
202 sh 'printenv > _output/parameters.txt'
203 sh "echo 'RESULT=$currentBuild.result' >> _output/parameters.txt"
206 archiveArtifacts artifacts: '_output/**/*.*', followSymlinks: false
207 sh "tar -czvf ${id}.tar.gz -C _output ."
208 withCredentials([string(credentialsId: 'nsm-nordix-artifactory-api-key', variable: 'API_KEY')]) {
209 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'"
211 } catch (Exception e) {
216 def ReportMeridio(success, failure) {
218 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()
219 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()
220 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()
221 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()
222 echo "Meridio: $formatted"
223 badge('meridio-e2e-kind-meridio', 'Meridio', formatted)
227 def ReportTAPA(success, failure) {
229 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()
230 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()
231 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()
232 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()
233 echo "TAPA: $formatted"
234 badge('meridio-e2e-kind-tapa', 'TAPA', formatted)
238 def ReportNSM(success, failure) {
240 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()
241 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()
242 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()
243 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()
244 echo "NSM: $formatted"
245 badge('meridio-e2e-kind-nsm', 'NSM', formatted)
249 def ReportIPFamily(success, failure) {
251 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()
252 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()
253 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()
254 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()
255 echo "IP Family: $formatted"
256 badge('meridio-e2e-kind-ip-family', 'IP Family', formatted)
260 def ReportKubernetes(success, failure) {
262 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()
263 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()
264 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()
265 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()
266 echo "Kubernetes: $formatted"
267 badge('meridio-e2e-kind-kubernetes', 'Kubernetes', formatted)
271 def badge(id, subject, message) {
272 addEmbeddableBadgeConfiguration(id: "${id}", subject: "${subject}", color: '#0B1F67', status: "$message")
275 echo '{' >> _output/${id}.json
276 echo '"schemaVersion": 1,' >> _output/${id}.json
277 echo '"label": "${subject}",' >> _output/${id}.json
278 echo '"message": "${message}",' >> _output/${id}.json
279 echo '"color": "#0B1F67"' >> _output/${id}.json
280 echo '}' >> _output/${id}.json
284 // Raise error in Jenkins job
292 // Cleanup directory and kind cluster
294 def command = 'make -s -C docs/demo/scripts/kind/ clean'
295 ExecSh(command).call()
300 def ExecSh(command) {
302 if (env.DRY_RUN != 'true') {