Meridio: update node to 2204
[infra/cicd.git] / jjb / nsm / e2e.Jenkinsfile
1 /*
2 Copyright (c) 2022 Nordix Foundation
3
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
7
8     http://www.apache.org/licenses/LICENSE-2.0
9
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.
15 */
16 import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
17
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
26
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
37         def seed = params.SEED
38
39         stage('Clone/Checkout') {
40             git branch: default_branch, url: git_project
41             checkout([
42                 $class: 'GitSCM',
43                 branches: [[name: current_branch]],
44                 extensions: [],
45                 userRemoteConfigs: [[
46                     refspec: '+refs/pull/*/head:refs/remotes/origin/pr/*',
47                     url: git_project
48                 ]]
49             ])
50             sh 'git show'
51         }
52         timeout(60) {
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"
55
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"
57                 try {
58                     ExecSh(command).call()
59                 } catch (Exception e) {
60                     unstable 'Environment setup failed'
61                     currentBuild.result = 'FAILURE'
62                 }
63             }
64             stage('E2E') {
65                 if (currentBuild.result != 'FAILURE') {
66                     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\""
67                     try {
68                         ExecSh(command).call()
69                         currentBuild.result = 'SUCCESS'
70                     } catch (Exception e) {
71                         unstable 'E2E Tests failed'
72                         currentBuild.result = 'FAILURE'
73                     }
74                 } else {
75                     Utils.markStageSkippedForConditional('E2E')
76                 }
77             }
78         }
79         stage('Report') {
80             try {
81                 Report().call()
82             } catch (Exception e) {
83                 unstable 'Failed to create the report'
84             }
85         }
86         stage('Next') {
87             if (next == true && currentBuild.result != 'ABORTED') {
88                 Next(next, number_of_workers, environment_name, focus, skip, current_branch).call()
89             } else {
90                 Utils.markStageSkippedForConditional('Next')
91             }
92         }
93         stage('Cleanup') {
94             Cleanup()
95         }
96     }
97 }
98
99 def Next(next, number_of_workers, environment_name, focus, skip, current_branch) {
100     return {
101         def meridio_version = GetMeridioVersion()
102         def tapa_version = GetTAPAVersion()
103         def nsm_version = GetNSMVersion()
104         def kubernetes_version = GetKubernetesVersion()
105         def ip_family = GetIPFamily()
106         def seed = GetSeed()
107         echo "Meridio version: $meridio_version / TAPA version: $tapa_version / NSM version: $nsm_version / IP Family: $ip_family / Kubernetes version: $kubernetes_version / Seed: $seed"
108         build job: 'meridio-e2e-test-kind', parameters: [
109                 string(name: 'NEXT', value: 'true'),
110                 string(name: 'MERIDIO_VERSION', value: "$meridio_version"),
111                 string(name: 'TAPA_VERSION', value: "$tapa_version"),
112                 string(name: 'KUBERNETES_VERSION', value: "$kubernetes_version"),
113                 string(name: 'NSM_VERSION', value: "$nsm_version"),
114                 string(name: 'IP_FAMILY', value: "$ip_family"),
115                 string(name: 'NUMBER_OF_WORKERS', value: "$number_of_workers"),
116                 string(name: 'ENVIRONMENT_NAME', value: "$environment_name"),
117                 string(name: 'SEED', value: "$seed"),
118                 string(name: 'FOCUS', value: "$focus"),
119                 string(name: 'SKIP', value: "$skip"),
120                 string(name: 'CURRENT_BRANCH', value: "$current_branch"),
121                 string(name: 'DRY_RUN', value: env.DRY_RUN)
122             ], wait: false
123     }
124 }
125
126 def GetMeridioVersion() {
127     def number_of_versions = sh(script: 'cat test/e2e/environment/kind-helm/test-scope.yaml | yq ".Meridio[]" | wc -l', returnStdout: true).trim()
128     def index_of_version_temp = sh(script: "shuf -i 1-$number_of_versions -n1", returnStdout: true).trim()
129     def index_of_version = sh(script: "expr $index_of_version_temp - 1 || true", returnStdout: true).trim()
130     return sh(script: "cat test/e2e/environment/kind-helm/test-scope.yaml | yq '.Meridio[$index_of_version]'", returnStdout: true).trim()
131 }
132
133 def GetTAPAVersion() {
134     def number_of_versions = sh(script: 'cat test/e2e/environment/kind-helm/test-scope.yaml | yq ".TAPA[]" | 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/kind-helm/test-scope.yaml | yq '.TAPA[$index_of_version]'", returnStdout: true).trim()
138 }
139
140 def GetNSMVersion() {
141     def number_of_versions = sh(script: 'cat test/e2e/environment/kind-helm/test-scope.yaml | yq ".NSM[]" | 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/kind-helm/test-scope.yaml | yq '.NSM[$index_of_version]'", returnStdout: true).trim()
145 }
146
147 def GetKubernetesVersion() {
148     def number_of_versions = sh(script: 'cat test/e2e/environment/kind-helm/test-scope.yaml | yq ".Kubernetes[]" | 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/kind-helm/test-scope.yaml | yq '.Kubernetes[$index_of_version]'", returnStdout: true).trim()
152 }
153
154 def GetIPFamily() {
155     def number_of_ip_family = sh(script: 'cat test/e2e/environment/kind-helm/test-scope.yaml | yq ".IP-Family[]" | wc -l', returnStdout: true).trim()
156     def index_of_ip_family_temp = sh(script: "shuf -i 1-$number_of_ip_family -n1", returnStdout: true).trim()
157     def index_of_ip_family = sh(script: "expr $index_of_ip_family_temp - 1 || true", returnStdout: true).trim()
158     return sh(script: "cat test/e2e/environment/kind-helm/test-scope.yaml | yq '.IP-Family[$index_of_ip_family]'", returnStdout: true).trim()
159 }
160
161 def GetSeed() {
162     return sh(script: 'shuf -i 1-2147483647 -n1', returnStdout: true).trim()
163 }
164
165 // http://JENKINS_URL/job/meridio-e2e-test-kind/api/json?tree=allBuilds[status,timestamp,id,result,description]{0,9}&pretty=true
166 def Report() {
167     return {
168         def jenkins_url = 'jenkins.nordix.org'
169
170         def success = ''
171         try {
172             success = sh(script: """
173             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")
174             success=\$(echo \"\$data\" | jq -r '.allBuilds[] | select(.result == \"SUCCESS\") | [.description] | @tsv' | grep -v \"^\$\")
175             echo \$success
176             """, returnStdout: true).trim()
177         } catch (Exception e) {
178         }
179
180         def failure = ''
181         try {
182             failure = sh(script: """
183             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")
184             failure=\$(echo \"\$data\" | jq -r '.allBuilds[] | select(.result == \"FAILURE\") | [.description] | @tsv' | grep -v \"^\$\")
185             echo \$failure
186             """, returnStdout: true).trim()
187         } catch (Exception e) {
188         }
189
190         ReportMeridio(success, failure).call()
191         ReportTAPA(success, failure).call()
192         ReportNSM(success, failure).call()
193         ReportIPFamily(success, failure).call()
194         ReportKubernetes(success, failure).call()
195
196         try {
197             archiveArtifacts artifacts: '_output/*', followSymlinks: false
198         } catch (Exception e) {
199         }
200     }
201 }
202
203 def ReportMeridio(success, failure) {
204     return {
205         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()
206         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()
207         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()
208         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()
209         echo "Meridio: $formatted"
210         badge('meridio-e2e-kind-meridio', 'Meridio', formatted)
211     }
212 }
213
214 def ReportTAPA(success, failure) {
215     return {
216         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()
217         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()
218         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()
219         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()
220         echo "TAPA: $formatted"
221         badge('meridio-e2e-kind-tapa', 'TAPA', formatted)
222     }
223 }
224
225 def ReportNSM(success, failure) {
226     return {
227         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()
228         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()
229         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()
230         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()
231         echo "NSM: $formatted"
232         badge('meridio-e2e-kind-nsm', 'NSM', formatted)
233     }
234 }
235
236 def ReportIPFamily(success, failure) {
237     return {
238         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()
239         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()
240         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()
241         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()
242         echo "IP Family: $formatted"
243         badge('meridio-e2e-kind-ip-family', 'IP Family', formatted)
244     }
245 }
246
247 def ReportKubernetes(success, failure) {
248     return {
249         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()
250         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()
251         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()
252         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()
253         echo "Kubernetes: $formatted"
254         badge('meridio-e2e-kind-kubernetes', 'Kubernetes', formatted)
255     }
256 }
257
258 def badge(id, subject, message) {
259     addEmbeddableBadgeConfiguration(id: "${id}", subject: "${subject}", color: '#0B1F67', status: "$message")
260     sh """
261     mkdir -p _output
262     echo '{' >> _output/${id}.json
263     echo '"schemaVersion": 1,' >> _output/${id}.json
264     echo '"label": "${subject}",' >> _output/${id}.json
265     echo '"message": "${message}",' >> _output/${id}.json
266     echo '"color": "#0B1F67"' >> _output/${id}.json
267     echo '}' >> _output/${id}.json
268     """
269 }
270
271 // Raise error in Jenkins job
272 def Error(e) {
273     return {
274         Cleanup()
275         error e
276     }
277 }
278
279 // Cleanup directory and kind cluster
280 def Cleanup() {
281     def command = 'make -s -C docs/demo/scripts/kind/ clean'
282     ExecSh(command).call()
283     cleanWs()
284 }
285
286 // Execute command
287 def ExecSh(command) {
288     return {
289         if (env.DRY_RUN != 'true') {
290             sh """
291                 . \${HOME}/.profile
292                 ${command}
293             """
294         } else {
295             echo "${command}"
296         }
297     }
298 }