blob: 5f68dbc3e9b0bd98afd1b0d77fc493752499f770 [file] [log] [blame]
Joey Armstrong65405412022-11-22 10:43:06 -05001// Copyright 2021-2022 Open Networking Foundation (ONF) and the ONF Contributors//
Hardik Windlass19605da2022-06-30 22:05:57 +05302// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// voltha-2.x e2e tests for openonu-go
15// uses bbsim to simulate OLT/ONUs
16
17library identifier: 'cord-jenkins-libraries@master',
18 retriever: modernSCM([
19 $class: 'GitSCMSource',
20 remote: 'https://gerrit.opencord.org/ci-management.git'
21])
22
23def clusterName = "kind-ci"
24
25def execute_test(testTarget, workflow, testLogging, teardown, testSpecificHelmFlags = "") {
26 def infraNamespace = "default"
27 def volthaNamespace = "voltha"
28 def logsDir = "$WORKSPACE/${testTarget}"
Joey Armstrong65405412022-11-22 10:43:06 -050029
30 stage('IAM')
31 {
32 script
33 {
34 String iam = [
35 'ci-management',
36 'jjb',
37 'pipeline',
38 'voltha',
39 'voltha-2.10',
40 'bbsim-tests.groovy'
41 ].join('/')
42 println("** ${iam}: ENTER")
43
44 String cmd = "which pkill"
45 def stream = sh(
46 returnStatus:false,
47 returnStdout: true,
48 script: cmd)
49 println(" ** ${cmd}:\n${stream}")
50 println("** ${iam}: LEAVE")
51 }
52 }
53
54 stage('Cleanup') {
Hardik Windlass19605da2022-06-30 22:05:57 +053055 if (teardown) {
56 timeout(15) {
57 script {
58 helmTeardown(["default", infraNamespace, volthaNamespace])
59 }
60 timeout(1) {
61 sh returnStdout: false, script: '''
62 # remove orphaned port-forward from different namespaces
63 ps aux | grep port-forw | grep -v grep | awk '{print $2}' | xargs --no-run-if-empty kill -9 || true
64 '''
65 }
66 }
67 }
68 }
69 stage('Deploy common infrastructure') {
70 sh '''
71 helm repo add onf https://charts.opencord.org
72 helm repo update
73 if [ ${withMonitoring} = true ] ; then
74 helm install nem-monitoring onf/nem-monitoring \
75 --set prometheus.alertmanager.enabled=false,prometheus.pushgateway.enabled=false \
76 --set kpi_exporter.enabled=false,dashboards.xos=false,dashboards.onos=false,dashboards.aaa=false,dashboards.voltha=false
77 fi
78 '''
79 }
80 stage('Deploy Voltha') {
81 if (teardown) {
82 timeout(10) {
83 script {
84
85 sh """
86 mkdir -p ${logsDir}
87 _TAG=kail-startup kail -n ${infraNamespace} -n ${volthaNamespace} > ${logsDir}/onos-voltha-startup-combined.log &
88 """
89
90 // if we're downloading a voltha-helm-charts patch, then install from a local copy of the charts
91 def localCharts = false
92 if (volthaHelmChartsChange != "" || gerritProject == "voltha-helm-charts") {
93 localCharts = true
94 }
95
96 // NOTE temporary workaround expose ONOS node ports
97 def localHelmFlags = extraHelmFlags.trim() + " --set global.log_level=${logLevel.toUpperCase()} " +
98 " --set onos-classic.onosSshPort=30115 " +
99 " --set onos-classic.onosApiPort=30120 " +
100 " --set onos-classic.onosOfPort=31653 " +
101 " --set onos-classic.individualOpenFlowNodePorts=true " + testSpecificHelmFlags
102
103 if (gerritProject != "") {
104 localHelmFlags = "${localHelmFlags} " + getVolthaImageFlags("${gerritProject}")
105 }
106
107 volthaDeploy([
108 infraNamespace: infraNamespace,
109 volthaNamespace: volthaNamespace,
110 workflow: workflow.toLowerCase(),
111 withMacLearning: enableMacLearning.toBoolean(),
112 extraHelmFlags: localHelmFlags,
113 localCharts: localCharts,
114 bbsimReplica: olts.toInteger(),
115 dockerRegistry: registry,
116 ])
117 }
118
119 // stop logging
120 sh """
121 P_IDS="\$(ps e -ww -A | grep "_TAG=kail-startup" | grep -v grep | awk '{print \$1}')"
122 if [ -n "\$P_IDS" ]; then
123 echo \$P_IDS
124 for P_ID in \$P_IDS; do
125 kill -9 \$P_ID
126 done
127 fi
128 cd ${logsDir}
129 gzip -k onos-voltha-startup-combined.log
130 rm onos-voltha-startup-combined.log
131 """
132 }
133 sh """
134 JENKINS_NODE_COOKIE="dontKillMe" _TAG="voltha-voltha-api" bash -c "while true; do kubectl port-forward --address 0.0.0.0 -n ${volthaNamespace} svc/voltha-voltha-api 55555:55555; done"&
135 JENKINS_NODE_COOKIE="dontKillMe" _TAG="voltha-infra-etcd" bash -c "while true; do kubectl port-forward --address 0.0.0.0 -n ${infraNamespace} svc/voltha-infra-etcd 2379:2379; done"&
136 JENKINS_NODE_COOKIE="dontKillMe" _TAG="voltha-infra-kafka" bash -c "while true; do kubectl port-forward --address 0.0.0.0 -n ${infraNamespace} svc/voltha-infra-kafka 9092:9092; done"&
137 bbsimDmiPortFwd=50075
138 for i in {0..${olts.toInteger() - 1}}; do
139 JENKINS_NODE_COOKIE="dontKillMe" _TAG="bbsim\${i}" bash -c "while true; do kubectl port-forward --address 0.0.0.0 -n ${volthaNamespace} svc/bbsim\${i} \${bbsimDmiPortFwd}:50075; done"&
140 ((bbsimDmiPortFwd++))
141 done
142 if [ ${withMonitoring} = true ] ; then
143 JENKINS_NODE_COOKIE="dontKillMe" _TAG="nem-monitoring-prometheus-server" bash -c "while true; do kubectl port-forward --address 0.0.0.0 -n default svc/nem-monitoring-prometheus-server 31301:80; done"&
144 fi
145 ps aux | grep port-forward
146 """
147 // setting ONOS log level
148 script {
149 setOnosLogLevels([
150 onosNamespace: infraNamespace,
151 apps: [
152 'org.opencord.dhcpl2relay',
153 'org.opencord.olt',
154 'org.opencord.aaa',
155 'org.opencord.maclearner',
156 'org.onosproject.net.flowobjective.impl.FlowObjectiveManager',
157 'org.onosproject.net.flowobjective.impl.InOrderFlowObjectiveManager'
158 ],
159 logLevel: logLevel
160 ])
161 }
162 }
163 }
164 stage('Run test ' + testTarget + ' on ' + workflow + ' workFlow') {
165 sh """
166 if [ ${withMonitoring} = true ] ; then
167 mkdir -p $WORKSPACE/voltha-pods-mem-consumption-${workflow}
168 cd $WORKSPACE/voltha-system-tests
169 make vst_venv
170 source ./vst_venv/bin/activate || true
171 # Collect initial memory consumption
172 python scripts/mem_consumption.py -o $WORKSPACE/voltha-pods-mem-consumption-${workflow} -a 0.0.0.0:31301 -n ${volthaNamespace} || true
173 fi
174 """
175 sh """
176 mkdir -p ${logsDir}
177 export ROBOT_MISC_ARGS="-d ${logsDir} ${params.extraRobotArgs} "
178 ROBOT_MISC_ARGS+="-v ONOS_SSH_PORT:30115 -v ONOS_REST_PORT:30120 -v NAMESPACE:${volthaNamespace} -v INFRA_NAMESPACE:${infraNamespace} -v container_log_dir:${logsDir} -v logging:${testLogging}"
179 export KVSTOREPREFIX=voltha/voltha_voltha
180
181 make -C $WORKSPACE/voltha-system-tests ${testTarget} || true
182 """
183 getPodsInfo("${logsDir}")
184 sh """
185 set +e
186 # collect logs collected in the Robot Framework StartLogging keyword
187 cd ${logsDir}
188 gzip *-combined.log || true
189 rm *-combined.log || true
190 """
191 sh """
192 if [ ${withMonitoring} = true ] ; then
193 cd $WORKSPACE/voltha-system-tests
194 source ./vst_venv/bin/activate || true
195 # Collect memory consumption of voltha pods once all the tests are complete
196 python scripts/mem_consumption.py -o $WORKSPACE/voltha-pods-mem-consumption-${workflow} -a 0.0.0.0:31301 -n ${volthaNamespace} || true
197 fi
198 """
199 }
200}
201
202def collectArtifacts(exitStatus) {
203 getPodsInfo("$WORKSPACE/${exitStatus}")
204 sh """
205 kubectl logs -n voltha -l app.kubernetes.io/part-of=voltha > $WORKSPACE/${exitStatus}/voltha.log || true
206 """
207 archiveArtifacts artifacts: '**/*.log,**/*.gz,**/*.txt,**/*.html,**/voltha-pods-mem-consumption-att/*,**/voltha-pods-mem-consumption-dt/*,**/voltha-pods-mem-consumption-tt/*'
208 sh '''
209 sync
210 pkill kail || true
211 which voltctl
212 md5sum $(which voltctl)
213 '''
214 step([$class: 'RobotPublisher',
215 disableArchiveOutput: false,
216 logFileName: "**/*/log*.html",
217 otherFiles: '',
218 outputFileName: "**/*/output*.xml",
219 outputPath: '.',
220 passThreshold: 100,
221 reportFileName: "**/*/report*.html",
222 unstableThreshold: 0,
223 onlyCritical: true]);
224}
225
226pipeline {
227
228 /* no label, executor is determined by JJB */
229 agent {
230 label "${params.buildNode}"
231 }
232 options {
233 timeout(time: "${timeout}", unit: 'MINUTES')
234 }
235 environment {
236 KUBECONFIG="$HOME/.kube/kind-${clusterName}"
237 VOLTCONFIG="$HOME/.volt/config"
238 PATH="$PATH:$WORKSPACE/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
239 DIAGS_PROFILE="VOLTHA_PROFILE"
240 SSHPASS="karaf"
241 }
242 stages {
243 stage('Download Code') {
244 steps {
245 getVolthaCode([
246 branch: "${branch}",
247 gerritProject: "${gerritProject}",
248 gerritRefspec: "${gerritRefspec}",
249 volthaSystemTestsChange: "${volthaSystemTestsChange}",
250 volthaHelmChartsChange: "${volthaHelmChartsChange}",
251 ])
252 }
253 }
254 stage('Build patch') {
255 // build the patch only if gerritProject is specified
256 when {
257 expression {
258 return !gerritProject.isEmpty()
259 }
260 }
261 steps {
262 // NOTE that the correct patch has already been checked out
263 // during the getVolthaCode step
264 buildVolthaComponent("${gerritProject}")
265 }
266 }
267 stage('Create K8s Cluster') {
268 steps {
269 script {
270 def clusterExists = sh returnStdout: true, script: """
271 kind get clusters | grep ${clusterName} | wc -l
272 """
273 if (clusterExists.trim() == "0") {
274 createKubernetesCluster([nodes: 3, name: clusterName])
275 }
276 }
277 }
278 }
279 stage('Replace voltctl') {
280 // if the project is voltctl override the downloaded one with the built one
281 when {
282 expression {
283 return gerritProject == "voltctl"
284 }
285 }
286 steps{
287 sh """
288 mv `ls $WORKSPACE/voltctl/release/voltctl-*-linux-amd*` $WORKSPACE/bin/voltctl
289 chmod +x $WORKSPACE/bin/voltctl
290 """
291 }
292 }
293 stage('Load image in kind nodes') {
294 when {
295 expression {
296 return !gerritProject.isEmpty()
297 }
298 }
299 steps {
300 loadToKind()
301 }
302 }
303 stage('Parse and execute tests') {
304 steps {
305 script {
306 def tests = readYaml text: testTargets
307
308 for(int i = 0;i<tests.size();i++) {
309 def test = tests[i]
310 def target = test["target"]
311 def workflow = test["workflow"]
312 def flags = test["flags"]
313 def teardown = test["teardown"].toBoolean()
314 def logging = test["logging"].toBoolean()
315 def testLogging = 'False'
316 if (logging) {
317 testLogging = 'True'
318 }
319 println "Executing test ${target} on workflow ${workflow} with logging ${testLogging} and extra flags ${flags}"
320 execute_test(target, workflow, testLogging, teardown, flags)
321 }
322 }
323 }
324 }
325 }
326 post {
327 aborted {
328 collectArtifacts("aborted")
329 }
330 failure {
331 collectArtifacts("failed")
332 }
333 always {
334 collectArtifacts("always")
335 }
336 }
337}
Joey Armstrong65405412022-11-22 10:43:06 -0500338
339// EOF