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')
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()
203 archiveArtifacts artifacts: '_output/**/*.*', followSymlinks: false
204 } catch (Exception e) {
209 def ReportMeridio(success, failure) {
211 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()
212 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()
213 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()
214 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()
215 echo "Meridio: $formatted"
216 badge('meridio-e2e-kind-meridio', 'Meridio', formatted)
220 def ReportTAPA(success, failure) {
222 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()
223 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()
224 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()
225 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()
226 echo "TAPA: $formatted"
227 badge('meridio-e2e-kind-tapa', 'TAPA', formatted)
231 def ReportNSM(success, failure) {
233 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()
234 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()
235 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()
236 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()
237 echo "NSM: $formatted"
238 badge('meridio-e2e-kind-nsm', 'NSM', formatted)
242 def ReportIPFamily(success, failure) {
244 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()
245 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()
246 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()
247 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()
248 echo "IP Family: $formatted"
249 badge('meridio-e2e-kind-ip-family', 'IP Family', formatted)
253 def ReportKubernetes(success, failure) {
255 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()
256 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()
257 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()
258 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()
259 echo "Kubernetes: $formatted"
260 badge('meridio-e2e-kind-kubernetes', 'Kubernetes', formatted)
264 def badge(id, subject, message) {
265 addEmbeddableBadgeConfiguration(id: "${id}", subject: "${subject}", color: '#0B1F67', status: "$message")
268 echo '{' >> _output/${id}.json
269 echo '"schemaVersion": 1,' >> _output/${id}.json
270 echo '"label": "${subject}",' >> _output/${id}.json
271 echo '"message": "${message}",' >> _output/${id}.json
272 echo '"color": "#0B1F67"' >> _output/${id}.json
273 echo '}' >> _output/${id}.json
277 // Raise error in Jenkins job
285 // Cleanup directory and kind cluster
287 def command = 'make -s -C docs/demo/scripts/kind/ clean'
288 ExecSh(command).call()
293 def ExecSh(command) {
295 if (env.DRY_RUN != 'true') {