blob: 52ad12ca53eb422c471ac86e236c31eef9cef6d7 [file] [log] [blame]
David Bainbridge117d23e2019-09-30 20:37:51 +00001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
David Bainbridge117d23e2019-09-30 20:37:51 +000014# voltctl common functions
15
16*** Settings ***
17Documentation Library for various utilities
18Library SSHLibrary
David Bainbridge117d23e2019-09-30 20:37:51 +000019Library String
20Library DateTime
21Library Process
22Library Collections
23Library RequestsLibrary
24Library OperatingSystem
25
26*** Keywords ***
27Lookup Service IP
28 [Arguments] ${namespace} ${name}
David Bainbridgef81cd642019-11-20 00:14:47 +000029 [Documentation] Uses kubectl to resolve a service name to an IP
Gilles Depatie675a2062019-10-22 12:44:42 -040030 ${rc} ${ip}= Run and Return Rc and Output
31 ... kubectl get svc -n ${namespace} ${name} -o jsonpath={.spec.clusterIP}
David Bainbridge117d23e2019-09-30 20:37:51 +000032 Should Be Equal as Integers ${rc} 0
33 [Return] ${ip}
34
35Lookup Service PORT
36 [Arguments] ${namespace} ${name}
David Bainbridgef81cd642019-11-20 00:14:47 +000037 [Documentation] Uses kubectl to resolve a service name to an PORT
Gilles Depatie675a2062019-10-22 12:44:42 -040038 ${rc} ${port}= Run and Return Rc and Output
39 ... kubectl get svc -n ${namespace} ${name} -o jsonpath={.spec.ports[0].port}
David Bainbridge117d23e2019-09-30 20:37:51 +000040 Should Be Equal as Integers ${rc} 0
41 [Return] ${port}
suraj gourd64356b2019-11-07 13:26:20 +000042
43Restart Pod
44 [Arguments] ${namespace} ${name}
45 [Documentation] Uses kubectl to force delete pod
suraj gour067451d2019-11-13 11:20:13 +000046 ${rc} ${restart_pod_name}= Run and Return Rc and Output
47 ... kubectl get pods -n ${namespace} | grep ${name} | awk 'NR==1{print $1}'
suraj gourd64356b2019-11-07 13:26:20 +000048 Log ${restart_pod_name}
suraj gour067451d2019-11-13 11:20:13 +000049 Should Not Be Empty ${restart_pod_name} Unable to parse pod name
Zack Williamsa8fe75a2020-01-10 14:25:27 -070050 ${rc} ${output}= Run and Return Rc and Output
51 ... kubectl delete pod ${restart_pod_name} -n ${namespace} --grace-period=0 --force
suraj gourd64356b2019-11-07 13:26:20 +000052 Log ${output}
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +000053
Scott Baker60e570d2020-02-02 22:10:13 -080054Exec Pod
55 [Arguments] ${namespace} ${name} ${command}
56 [Documentation] Uses kubectl to execute a command in the pod and return the output
57 ${rc} ${exec_pod_name}= Run and Return Rc and Output
58 ... kubectl get pods -n ${namespace} | grep ${name} | awk 'NR==1{print $1}'
59 Log ${exec_pod_name}
60 Should Not Be Empty ${exec_pod_name} Unable to parse pod name
61 ${rc} ${output}= Run and Return Rc and Output
62 ... kubectl exec -i ${exec_pod_name} -n ${namespace} -- ${command}
63 Log ${output}
64 [return] ${output}
65
66Exec Pod Separate Stderr
67 [Arguments] ${namespace} ${name} ${command}
68 [Documentation] Uses kubectl to execute a command in the pod and return the stderr and stdout
69 ${rc} ${exec_pod_name}= Run and Return Rc and Output
70 ... kubectl get pods -n ${namespace} | grep ${name} | awk 'NR==1{print $1}'
71 Log ${exec_pod_name}
72 Should Not Be Empty ${exec_pod_name} Unable to parse pod name
73 @{args}= Split String ${command}
74 ${result}= Run Process
75 ... kubectl exec -i ${exec_pod_name} -n ${namespace} -- @{args}
76 ${stdout}= Set Variable ${result.stdout}
77 ${stderr}= Set Variable ${result.stderr}
78 Log ${stdout}
79 Log ${stderr}
80 [return] ${stdout} ${stderr}
81
82Apply Kubernetes Resources
83 [Arguments] ${resource_yaml} ${namespace}
84 [Documentation] Use kubectl to create resources given a yaml file
85 ${rc} Run and Return Rc
86 ... kubectl apply -n ${namespace} -f ${resource_yaml}
87 Should Be Equal as Integers ${rc} 0
88
suraj gour1ecfae92019-12-20 15:11:40 +000089Validate Pod Status
90 [Arguments] ${pod_name} ${namespace} ${expectedStatus}
91 [Documentation] To run the kubectl command and check the status of the given pod matches the expected status
Andy Bavierb63f6d22020-03-12 15:34:37 -070092 ${length}= Run kubectl get pod -n ${namespace} -o name | wc -l
93 ${matched}= Set Variable False
94 FOR ${index} IN RANGE ${length}
Zack Williamsa8fe75a2020-01-10 14:25:27 -070095 ${currentPodName}= Run
96 ... kubectl get pod -n ${namespace} -o=jsonpath="{.items[${index}].status.containerStatuses[0].name}"
suraj gour1ecfae92019-12-20 15:11:40 +000097 Log Required Pod : ${pod_name}
98 Log Current Pod: ${currentPodName}
Andy Bavierb63f6d22020-03-12 15:34:37 -070099 ${matched}= Set Variable If '${currentPodName}'=='${pod_name}' True False
100 Exit For Loop If ${matched}
suraj gour1ecfae92019-12-20 15:11:40 +0000101 END
Andy Bavierb63f6d22020-03-12 15:34:37 -0700102 Should Be True ${matched} No pod ${podname} found
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700103 ${currentStatusofPod}= Run
104 ... kubectl get pod -n ${namespace} -o=jsonpath="{.items[${index}].status.phase}"
suraj gour1ecfae92019-12-20 15:11:40 +0000105 Log ${currentStatusofPod}
106 Should Contain ${currentStatusofPod} ${expectedStatus}
107
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000108Verify All Voltha Pods For Any Error Logs
109 [Arguments] ${datetime}
110 [Documentation] This keyword checks for the error occurence in the voltha pods
111 &{errorPodDict} Create Dictionary
112 &{containerDict} Get Container Dictionary
113 FOR ${podName} IN @{PODLIST1}
114 ${containerName} Get From Dictionary ${containerDict} ${podName}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700115 ${rc} ${logOutput} Run And Return Rc And Output
116 ... kubectl logs --timestamps -n voltha --since-time=${datetime} ${containerName}
117 Run Keyword And Ignore Error
118 ... Run Keyword If '${logOutput}'=='${EMPTY}'
119 ... Run Keywords Log No Log found in pod ${podName}
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000120 ... AND Continue For Loop
121 ${errorDict} Check For Error Logs in Pod Type1 Given the Log Output ${logOutput}
122 ${returnStatusFlagList} Get Dictionary Keys ${errorDict}
123 ${returnStatusFlag} Get From List ${returnStatusFlagList} 0
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700124 Run Keyword And Ignore Error
125 ... Run Keyword If '${returnStatusFlag}'=='Nologfound'
126 ... Run Keywords Log No Error Log found in pod ${podName}
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000127 ... AND Continue For Loop
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700128 Run Keyword And Ignore Error
129 ... Run Keyword If '${returnStatusFlag}'=='UnexpectedErrorfound'
130 ... Run Keywords Log Unexpected Error Log found in pod ${podName}
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000131 ... AND Set to Dictionary ${errorPodDict} ${podName} ${errorDict}
132 END
133 FOR ${podName} IN @{PODLIST2}
134 ${containerName} Get From Dictionary ${containerDict} ${podName}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700135 ${rc} ${logOutput} Run And Return Rc And Output
136 ... kubectl logs --timestamps -n voltha --since-time=${datetime} ${containerName}
137 Run Keyword And Ignore Error
138 ... Run Keyword If '${logOutput}'=='${EMPTY}'
139 ... Run Keywords Log No Log found in pod ${podName}
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000140 ... AND Continue For Loop
141 ${errorDict} Check For Error Logs in Pod Type2 Given the Log Output ${logOutput}
142 ${returnStatusFlagList} Get Dictionary Keys ${errorDict}
143 ${returnStatusFlag} Get From List ${returnStatusFlagList} 0
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700144 Run Keyword And Ignore Error
145 ... Run Keyword If '${returnStatusFlag}'=='Nologfound'
146 ... Run Keywords Log No Error Log found in pod ${podName}
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000147 ... AND Continue For Loop
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700148 Run Keyword And Ignore Error
149 ... Run Keyword If '${returnStatusFlag}'=='UnexpectedErrorfound'
150 ... Run Keywords Log Unexpected Error Log found in pod ${podName}
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000151 ... AND Set to Dictionary ${errorPodDict} ${podName} ${errorDict}
152 END
153 Print to Console Error Statement logged in the following pods : ${errorPodDict}
154 [Return] ${errorPodDict}
155
156Check For Error Logs in Pod Type1 Given the Log Output
157 [Arguments] ${logOutput} ${logLevel}=error ${errorMessage}=${EMPTY}
158 [Documentation] Checks for error message in the particular list of pods
159 Log ${logOutput}
160 ${linesContainingLog} = Get Lines Matching Regexp ${logOutput} .*\s\${logLevel}.* partial_match=true
161 ${is_exec_status} ${output} Run Keyword And Ignore Error Should Be Empty ${linesContainingLog}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700162 ${returnStatusFlag} Set Variable If '${is_exec_status}'=='PASS'
163 ... Nologfound '${is_exec_status}'=='FAIL' Errorlogfound
164 ${linesContainingError} = Get Lines Matching Regexp
165 ... ${logOutput} .*\s\${logLevel}.*${errorMessage} partial_match=true
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000166 ${is_exec_status} ${output} Run Keyword And Ignore Error Should Be Empty ${linesContainingError}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700167 ${returnStatusFlag} Set Variable If '${is_exec_status}'=='PASS'
168 ... UnexpectedErrorfound '${is_exec_status}'=='FAIL' MatchingErrorlogfound
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000169 Log {linesContainingError}
170 &{errorDict} Create Dictionary ${returnStatusFlag} ${linesContainingLog}
171 [Return] ${errorDict}
172
173Check For Error Logs in Pod Type2 Given the Log Output
174 [Arguments] ${logOutput} ${logLevel}=warn ${errorMessage}=${EMPTY}
175 [Documentation] Checks for error message in the particular set of pods
176 Log ${logOutput}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700177 ${linesContainingLog} = Get Lines Matching Regexp
178 ... ${logOutput} .*?\s.*level.*${logLevel}.* partial_match=true
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000179 ${is_exec_status} ${output} Run Keyword And Ignore Error Should Be Empty ${linesContainingLog}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700180 ${returnStatusFlag} Set Variable If '${is_exec_status}'=='PASS'
181 ... Nologfound '${is_exec_status}'=='FAIL' Errorlogfound
182 ${linesContainingError} = Get Lines Matching Regexp
183 ... ${logOutput} .*?\s.*level.*${logLevel}.*msg.*${errorMessage} partial_match=true
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000184 ${is_exec_status} ${output} Run Keyword And Ignore Error Should Be Empty ${linesContainingError}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700185 ${returnStatusFlag} Set Variable If '${is_exec_status}'=='PASS'
186 ... UnexpectedErrorfound '${is_exec_status}'=='FAIL' MatchingErrorlogfound
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000187 Log {linesContainingError}
188 &{errorDict} Create Dictionary ${returnStatusFlag} ${linesContainingLog}
189 [Return] ${errorDict}
190
191Get Container Dictionary
192 [Documentation] Creates a mapping for pod name and container name and returns the same
193 &{containerDict} Create Dictionary
194 ${containerName} Set Variable ${EMPTY}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700195 ${podName} Run kubectl get deployment -n voltha | awk 'NR>1 {print $1}'
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000196 @{podNameList}= Split To Lines ${podName}
197 Append To List ${podNameList} voltha-etcd-cluster voltha-kafka voltha-ro-core voltha-zookeeper
198 Log ${podNameList}
199 #Creatiing dictionary to correspond pod name and container name
200 FOR ${pod} IN @{podNameList}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700201 ${containerName} Run kubectl get pod -n voltha | grep ${pod} | awk '{print $1}'
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000202 &{containerDict} Set To Dictionary ${containerDict} ${pod} ${containerName}
203 END
204 Log ${containerDict}
205 [Return] ${containerDict}
206
207Validate Error For Given Pods
208 [Arguments] ${datetime} ${podDict}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700209 [Documentation]
210 ... This keyword is used to get the list of pods if there is any unexpected error
211 ... in a particular pod(s) given the time-${datetime} from which the log needs to
212 ... be analysed and the dictionary of pods and the error in the dictionary format
213 ... ${podDict] .
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000214 ...
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700215 ... Usage: ${returnStatusFlag} Validate Error For Given Pods ${datetime} ${podDict}
216 ...
217 ... Arguments:
218 ...
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000219 ... ${datetime} = time from which the log needs to be taken
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700220 ... ${podDict} = Key-value pair of the pod name and the error msg
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000221 ...
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700222 ... Example: ${podDict} = Set Dictionary ${podDict} radius sample error message.
223 ...
224 ... In case the radius pod log has any other error than the expected
225 ... error, then the podname will be returned
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000226 ${podList} = Get Dictionary Keys ${podDict}
227 FOR ${podName} IN @{podList}
228 ${containerName} Get From Dictionary ${containerDict} ${podName}
229 ${expectedError} Get From Dictionary ${podDict} ${podName}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700230 ${rc} ${logOutput} Run And Return Rc And Output
231 ... kubectl logs --timestamps -n voltha --since-time=${datetime} ${containerName}
232 Run Keyword And Ignore Error
233 ... Run Keyword If '${logOutput}'=='${EMPTY}'
234 ... Run Keywords Log No Log found in pod ${podName}
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000235 ... AND Continue For Loop
236 ${returnStatusFlag} Check For Error Logs in Pod Type1 Given the Log Output ${logOutput}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700237 Run Keyword And Ignore Error
238 ... Run Keyword If '${returnStatusFlag}'=='Nologfound'
239 ... Run Keywords Log No Error Log found in pod ${podName}
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000240 ... AND Continue For Loop
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700241 Run Keyword And Ignore Error
242 ... Run Keyword If '${returnStatusFlag}'=='UnexpectedErrorfound'
243 ... Run Keywords Log Unexpected Error Log found in pod ${podName}
Gayathri.Selvan61fbcdb2019-11-14 05:08:19 +0000244 ... AND Append To List ${errorPodList} ${podName}
245 END
246 [Return] ${errorPodList}
247
David Bainbridgef81cd642019-11-20 00:14:47 +0000248Delete K8s Pod
249 [Arguments] ${namespace} ${name}
250 [Documentation] Uses kubectl to delete a named POD
251 ${rc} Run and Return Rc
252 ... kubectl delete -n ${namespace} pod/${name}
253 Should Be Equal as Integers ${rc} 0
254
hwchiu85695932019-12-18 08:05:25 +0000255Delete K8s Pods By Label
256 [Arguments] ${namespace} ${key} ${value}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700257 [Documentation] Uses kubectl to delete a PODs, filtering by label
hwchiu85695932019-12-18 08:05:25 +0000258 ${rc}= Run and Return Rc
259 ... kubectl -n ${namespace} delete pods -l${key}=${value}
260 Should Be Equal as Integers ${rc} 0
261
David Bainbridgef81cd642019-11-20 00:14:47 +0000262Scale K8s Deployment
263 [Arguments] ${namespace} ${name} ${count}
264 [Documentation] Uses kubectl to scale a named deployment
265 ${rc} Run and Return Rc
266 ... kubectl scale --replicas=${count} -n ${namespace} deploy/${name}
267 Should Be Equal as Integers ${rc} 0
268
269Pod Exists
270 [Arguments] ${namespace} ${name}
271 [Documentation] Succeeds it the named POD exists
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700272 ${rc} ${count} Run and Return Rc
273 ... kubectl get -n ${namespace} pod -o json | jq -r ".items[].metadata.name" | grep ${name}
Andy Bavierb63f6d22020-03-12 15:34:37 -0700274 Should Be True ${count}>0 Pod ${name} not found
David Bainbridgef81cd642019-11-20 00:14:47 +0000275
276Pod Does Not Exist
277 [Arguments] ${namespace} ${name}
278 [Documentation] Succeeds if the named POD does not exist
279 ${rc} ${count} Run and Return Rc And Output
280 ... kubectl get -n ${namespace} pod -o json | jq -r ".items[].metadata.name" | grep -c ${name}
281 Should Be Equal As Integers ${count} 0
Andy Bavierb63f6d22020-03-12 15:34:37 -0700282 Should Be True ${count}==0 Pod ${name} exists but should not
David Bainbridgef81cd642019-11-20 00:14:47 +0000283
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700284Pods Do Not Exist By Label
hwchiu85695932019-12-18 08:05:25 +0000285 [Arguments] ${namespace} ${key} ${value}
286 [Documentation] Succeeds if the named POD does not exist
287 ${rc} ${count} Run and Return Rc And Output
288 ... kubectl get -n ${namespace} pod -l${key}=${value} -o json | jq -r ".items[].metadata.name" | wc -l
289 Should Be Equal As Integers ${count} 0
Andy Bavierb63f6d22020-03-12 15:34:37 -0700290 Should Be True ${count}==0 Pod with label ${key}=${value} exists but should not
hwchiu85695932019-12-18 08:05:25 +0000291
David Bainbridgef81cd642019-11-20 00:14:47 +0000292Get Available Deployment Replicas
293 [Arguments] ${namespace} ${name}
294 [Documentation] Succeeds if the named POD exists and has a ready count > 0
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700295 ${rc} ${count} Run and Return Rc and Output
296 ... kubectl get -n ${namespace} deploy/${name} -o jsonpath='{.status.availableReplicas}'
David Bainbridgef81cd642019-11-20 00:14:47 +0000297 ${result}= Run Keyword If '${count}' == '' Set Variable 0
298 ... ELSE Set Variable ${count}
299 [Return] ${result}
300
301Check Expected Available Deployment Replicas
302 [Arguments] ${namespace} ${name} ${expected}
303 [Documentation] Succeeds if the named deployment has the expected number of available replicas
304 ${count}= Get Available Deployment Replicas ${namespace} ${name}
305 Should Be Equal As Integers ${expected} ${count}
306
307Get Deployment Replica Count
308 [Arguments] ${namespace} ${name}
309 [Documentation] Uses kubectl to fetch the number of configured replicas on a deployment
310 ${rc} ${value} Run and Return Rc and Output
311 ... kubectl -n ${namespace} get deploy/${name} -o 'jsonpath={.status.replicas}'
312 Should Be Equal as Integers ${rc} 0
313 ${replicas}= Run Keyword If '${value}' == '' Set Variable 0
314 ... ELSE Set Variable ${value}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700315 [Return] ${replicas}
David Bainbridgef81cd642019-11-20 00:14:47 +0000316
317Does Deployment Have Replicas
318 [Arguments] ${namespace} ${name} ${expected_count}
319 [Documentation] Uses kubectl to fetch the number of configured replicas on a deployment
320 ${rc} ${value} Run and Return Rc and Output
321 ... kubectl -n ${namespace} get deploy/${name} -o 'jsonpath={.status.replicas}'
322 Should Be Equal as Integers ${rc} 0
323 ${replicas}= Run Keyword If '${value}' == '' Set Variable 0
324 ... ELSE Set Variable ${value}
325 Should be Equal as Integers ${replicas} ${expected_count}
hwchiu85695932019-12-18 08:05:25 +0000326
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700327Pods Are Ready By Label
hwchiu85695932019-12-18 08:05:25 +0000328 [Arguments] ${namespace} ${key} ${value}
Zack Williamsa8fe75a2020-01-10 14:25:27 -0700329 [Documentation] Check that all pods with a label are ready
330 ${output}= Run
331 ... kubectl -n ${namespace} get pods -l ${key}=${value} -o=jsonpath="{.items[].status.containerStatuses[].ready}"
332 Should Not Contain ${output} "false"
Gayathri.Selvan49398962020-01-13 07:19:12 +0000333
hwchiu58af72d2020-01-14 00:50:35 +0000334Check Expected Running Pods Number By Label
335 [Arguments] ${namespace} ${key} ${value} ${number}
336 [Documentation] Succeeds if the desired pod has expected number replicas
337 ${rc} ${count} Run and Return Rc and Output
338 ... kubectl -n ${namespace} get pods -l ${key}=${value} -o json | jq -r ".items[].status.phase" | wc -l
339 Should Be Equal as Integers ${count} ${number}
Gayathri.Selvanf68ea4b2020-02-03 07:36:39 +0000340