blob: eb68a679cf6d827028518a784659d2f6393355ac [file] [log] [blame]
Zack Williams821c5022020-01-15 15:11:46 -07001# 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.
14
15*** Settings ***
16Documentation Library for various utilities
17Library SSHLibrary
18Library String
19Library DateTime
20Library Process
21Library Collections
22Library RequestsLibrary
23
24*** Keywords ***
25Login To Remote System
26 [Documentation] SSH into a remote host (and into a container on that host if container_type
27 ... and container_name are specified) and returns connection ID
28 [Arguments] ${ip} ${user} ${pass}=${None}
29 ... ${container_type}=${None} ${container_name}=${None}
30 ... ${prompt}=~$ ${prompt_timeout}=15s ${container_prompt}=#
31 ${conn_id}= SSHLibrary.Open Connection ${ip} prompt=${prompt} timeout=${prompt_timeout}
32 Run Keyword If '${pass}' != '${None}'
33 ... SSHLibrary.Login ${user} ${pass}
34 ... ELSE
35 ... SSHLibrary.Login With Public Key ${user} %{HOME}/.ssh/id_rsa
36 # Login to the lxc container
37 Run Keyword If '${container_type}' == 'LXC' Run Keywords
38 ... SSHLibrary.Write lxc exec ${container_name} /bin/bash
39 ... AND
40 ... SSHLibrary.Read Until ${container_prompt}
41 ... AND
42 ... SSHLibrary.Set Client Configuration prompt=${container_prompt}
43 # Login to the k8s container
44 # FIXME: This fails if /bin/bash isn't installed in the container, run on command
45 Run Keyword If '${container_type}' == 'K8S' Run Keywords
46 ... SSHLibrary.Write kubectl -n $(kubectl get pods --all-namespaces | grep ${container_name} | awk '{print $1}') exec ${container_name} -it /bin/bash
47 ... AND
48 ... SSHLibrary.Read Until ${container_prompt}
49 ... AND
50 ... SSHLibrary.Set Client Configuration prompt=${container_prompt}
51 # Try to switch to root user
52 # FIXME: Is is useful in the LXC/K8S cases?
53 ${conn}= SSHLibrary.Get Connection ${conn_id}
54 Run Keyword And Ignore Error
55 ... SSHLibrary.Write sudo -s
56 ${output}= SSHLibrary.Read Until Regexp \#|${conn.prompt}|password for ${user}:
57 Run Keyword If 'password for ${user}:' not in '''${output}'''
58 ... Return From Keyword ${conn_id}
59 SSHLibrary.Set Client Configuration prompt=\#
60 SSHLibrary.Write ${pass}
61 SSHLibrary.Read Until Prompt
62 [Return] ${conn_id}
63
64Logout From Remote System
65 [Documentation] Exit from the SSH session to a remote host
66 [Arguments] ${conn_id}
67 SSHLibrary.Switch Connection ${conn_id}
68 SSHLibrary.Close Connection
69
70Run Command On Remote System
71 [Documentation] Executes a command on remote host and returns output
72 [Arguments] ${cmd} ${conn_id} ${user} ${pass}=${None}
73 ${conn}= SSHLibrary.Get Connection ${conn_id}
74 SSHLibrary.Switch Connection ${conn_id}
75 SSHLibrary.Write ${cmd}
76 ${output}= SSHLibrary.Read Until Regexp ${conn.prompt}|password for ${user}:
77 Run Keyword If 'password for ${user}:' not in '''${output}'''
78 ... Return From Keyword ${output}
79 SSHLibrary.Write ${pass}
80 ${output}= SSHlibrary.Read Until Prompt
81 [Return] ${output}
82
83Login And Run Command On Remote System
84 [Documentation] SSH into a remote host (and into a container on that host if container_type
85 ... and container_name are specified), switch to root user, executes command, return output
86 [Arguments] ${cmd} ${ip} ${user} ${pass}=${None}
87 ... ${container_type}=${None} ${container_name}=${None}
88 ... ${prompt}=~$ ${prompt_timeout}=50s ${container_prompt}=#
89 ${conn_id} Login To Remote System ${ip} ${user} ${pass}
90 ... ${container_type} ${container_name}
91 ... ${prompt} ${prompt_timeout} ${container_prompt}
92 ${output}= Run Command On Remote System ${cmd} ${conn_id} ${user} ${pass}
93 Log ${output}
94 # FIXME: Look into persisting SSH connection rather than tearing it up/down repeatedly
95 Logout From Remote System ${conn_id}
96 [Return] ${output}
97
98Execute Command Locally
99 [Documentation] Superfluous, use the 'Run' keyword instead which this wraps
100 [Arguments] ${cmd}
101 ${output}= Run ${cmd}
102 [Return] ${output}
103
104Get Docker Container ID
105 [Documentation] Retrieves the id of the requested docker container running locally
106 [Arguments] ${container_name}
107 ${container_id}= Run docker ps | grep ${container_name} | awk '{print $1}'
108 Log ${container_id}
109 [Return] ${container_id}
110
111Remove Value From List
112 [Documentation] Removes a value from a dictionary
113 [Arguments] ${list} ${val}
114 ${length}= Get Length ${list}
115 FOR ${INDEX} IN RANGE 0 ${length}
116 Log ${list[${INDEX}]}
117 ${value}= Get Dictionary Values ${list[${INDEX}]}
118 Log ${value[0]}
119 Run Keyword If '${value[0]}' == '${val}' Remove From List ${list} ${INDEX}
120 Run Keyword If '${value[0]}' == '${val}' Exit For Loop
121 END
122
123Test Ping
124 [Documentation] SSH's into src and attempts to ping dest.
125 ... Status determines if ping should pass | fail
126 [Arguments] ${status} ${src} ${user} ${pass}
127 ... ${dest} ${interface} ${prompt}=$ ${prompt_timeout}=60s
128 ${conn_id}= SSHLibrary.Open Connection
129 ... ${src} prompt=${prompt} timeout=${prompt_timeout}
130 SSHLibrary.Login ${user} ${pass}
131 ${result}= SSHLibrary.Execute Command
132 ... ping -I ${interface} -c 5 ${dest}
133 SSHLibrary.Close Connection
134 Log ${result}
135 Run Keyword If '${status}' == 'PASS'
136 ... Should Contain ${result} 64 bytes
137 Run Keyword If '${status}' == 'PASS'
138 ... Should Contain ${result} 0% packet loss
139 Run Keyword If '${status}' == 'PASS'
140 ... Should Not Contain ${result} 100% packet loss
141 Run Keyword If '${status}' == 'PASS'
142 ... Should Not Contain ${result} 80% packet loss
143 Run Keyword If '${status}' == 'PASS'
144 ... Should Not Contain ${result} 60% packet loss
145 Run Keyword If '${status}' == 'PASS'
146 ... Should Not Contain ${result} 40% packet loss
147 Run Keyword If '${status}' == 'PASS'
148 ... Should Not Contain ${result} 20% packet loss
149 Run Keyword If '${status}' == 'PASS'
150 ... Should Not Contain ${result} Destination Host Unreachable
151 Run Keyword If '${status}' == 'FAIL'
152 ... Should Not Contain ${result} 64 bytes
153 Run Keyword If '${status}' == 'FAIL'
154 ... Should Contain ${result} 100% packet loss
155 Log To Console \n ${result}
156
157Check Ping Result
158 [Documentation] Check the output of the 'ping' command
159 [Arguments] ${reachable} ${result}
160 Run Keyword If '${reachable}' == 'True'
161 ... Should Contain ${result} 64 bytes
162 Run Keyword If '${reachable}' == 'True'
Hardik Windlass70761af2021-10-05 09:25:56 +0000163 ... Should Contain Any ${result} 0% packet loss 0.0% packet loss 1% packet loss
164 ... 2% packet loss 3% packet loss 4% packet loss
Zack Williams821c5022020-01-15 15:11:46 -0700165 Run Keyword If '${reachable}' == 'True'
166 ... Should Not Contain Any ${result} 100% packet loss 100.0% packet loss
167 Run Keyword If '${reachable}' == 'False'
168 ... Should Not Contain ${result} 64 bytes
169 Run Keyword If '${reachable}' == 'False'
170 ... Should Contain Any ${result} 100% packet loss 100.0% packet loss
171
172Check Ping
173 [Documentation] Run 'ping' on remote system and check output
174 [Arguments] ${ping_should_pass} ${dst_ip} ${iface} ${ip}
175 ... ${user} ${pass}=${None} ${container_type}=${None} ${container_name}=${None}
176 ${result}= Login And Run Command On Remote System
Hardik Windlass70761af2021-10-05 09:25:56 +0000177 ... ping -I ${iface} -c 30 ${dst_ip}
Zack Williams821c5022020-01-15 15:11:46 -0700178 ... ${ip} ${user} ${pass} ${container_type} ${container_name}
179 Check Ping Result ${ping_should_pass} ${result}
180
181Check Remote System Reachability
182 [Documentation] Check if the specified IP address is reachable or not
183 [Arguments] ${reachable} ${ip}
184 ${result}= Run ping -c 3 ${ip}
185 Check Ping Result ${reachable} ${result}
186
187Kill Linux Process
188 [Documentation] Kill a process on a remote system
189 [Arguments] ${process} ${ip} ${user} ${pass}=${None}
190 ... ${container_type}=${None} ${container_name}=${None}
191 ${rc}= Login And Run Command On Remote System
192 ... kill $(ps aux | grep '${process}' | awk '{print $2}'); echo $?
193 ... ${ip} ${user} ${pass} ${container_type} ${container_name}
194 Should Be Equal As Integers ${rc} 0
195
196Check Remote File Contents
Andy Bavier95032202020-02-26 06:25:56 -0700197 [Documentation] Check if file on remote system matches a Robot regex
Zack Williams821c5022020-01-15 15:11:46 -0700198 [Arguments] ${file_should_exist} ${file} ${pattern}
199 ... ${ip} ${user} ${pass}=${None}
200 ... ${container_type}=${None} ${container_name}=${None} ${prompt}=~$
201 ${output}= Login And Run Command On Remote System
Andy Bavier95032202020-02-26 06:25:56 -0700202 ... cat ${file}
Zack Williams821c5022020-01-15 15:11:46 -0700203 ... ${ip} ${user} ${pass} ${container_type} ${container_name} ${prompt}
204 # FIXME: Comparison against truthy value
205 Run Keyword If '${file_should_exist}' == 'True'
Andy Bavier95032202020-02-26 06:25:56 -0700206 ... Should Match Regexp ${output} ${pattern}
Zack Williams821c5022020-01-15 15:11:46 -0700207 ... ELSE
Andy Bavier95032202020-02-26 06:25:56 -0700208 ... Should Not Match Regexp ${output} ${pattern}
Zack Williams821c5022020-01-15 15:11:46 -0700209
210Set Deployment Config Variables
211 [Documentation] Parses through the given deployment config and sets all the "src" and "dst" variables
212 ${source}= Evaluate ${hosts}.get("src")
213 ${length_src}= Get Length ${source}
214 ${src}= Set Variable src
215 FOR ${INDEX} IN RANGE 0 ${length_src}
216 Set Suite Variable ${${src}${INDEX}} ${source[${INDEX}]}
217 END
218 ${destination}= Evaluate ${hosts}.get("dst")
219 ${length_dst}= Get Length ${destination}
220 ${dst}= Set Variable dst
221 FOR ${INDEX} IN RANGE 0 ${length_dst}
222 Set Suite Variable ${${dst}${INDEX}} ${destination[${INDEX}]}
223 END