Migrate bgpcep suites restconf calls to rfc8040
[integration/test.git] / csit / libraries / SSHKeywords.robot
1 *** Settings ***
2 Documentation     Resource enhancing SSHLibrary with Keywords used in multiple suites.
3 ...
4 ...               Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
5 ...
6 ...               This program and the accompanying materials are made available under the
7 ...               terms of the Eclipse Public License v1.0 which accompanies this distribution,
8 ...               and is available at http://www.eclipse.org/legal/epl-v10.html
9 ...
10 ...
11 ...               Some suites evolved utility Keywords re-usable with other suites.
12 ...               When the Keywords assume a SSH session is active,
13 ...               and if the Keywords do not fit into a more specific Resource,
14 ...               you can place them here.
15 Library           SSHLibrary
16 Resource          ${CURDIR}/Utils.robot
17 Resource          ../variables/Variables.robot
18
19 *** Variables ***
20 ${SSHKeywords__current_remote_working_directory}    .
21 ${SSHKeywords__current_venv_path}    /tmp/defaultvenv
22 ${NETSTAT_COMMAND}    netstat -punta
23
24 *** Keywords ***
25 Open_Connection_To_ODL_System
26     [Arguments]    ${ip_address}=${ODL_SYSTEM_IP}    ${timeout}=10s
27     [Documentation]    Open a connection to the ODL system at ${ip_address} and return its identifier.
28     ${odl_connection} =    SSHLibrary.Open_Connection    ${ip_address}    prompt=${ODL_SYSTEM_PROMPT}    timeout=${timeout}
29     Flexible_Controller_Login
30     [Return]    ${odl_connection}
31
32 Open_Connection_To_Tools_System
33     [Arguments]    ${ip_address}=${TOOLS_SYSTEM_IP}    ${timeout}=10s    ${prompt}=${TOOLS_SYSTEM_PROMPT}
34     [Documentation]    Open a connection to the tools system at ${ip_address} and return its identifier.
35     ${tools_connection} =    SSHLibrary.Open_Connection    ${ip_address}    prompt=${prompt}    timeout=${timeout}
36     Flexible_Mininet_Login
37     [Return]    ${tools_connection}
38
39 Restore_Current_Ssh_Connection_From_Index
40     [Arguments]    ${connection_index}
41     [Documentation]    Restore active SSH connection in SSHLibrary to given index.
42     ...
43     ...    Restore the currently active connection state in
44     ...    SSHLibrary to match the state returned by "Switch
45     ...    Connection" or "Get Connection". More specifically makes
46     ...    sure that there will be no active connection when the
47     ...    \${connection_index} reported by these means is None.
48     ...
49     ...    There is a misfeature in SSHLibrary: Invoking "SSHLibrary.Switch_Connection"
50     ...    and passing None as the "index_or_alias" argument to it has exactly the
51     ...    same effect as invoking "Close Connection".
52     ...    https://github.com/robotframework/SSHLibrary/blob/master/src/SSHLibrary/library.py#L560
53     ...
54     ...    We want to have Keyword which will "switch out" to previous
55     ...    "no connection active" state without killing the background one.
56     ...
57     ...    As some suites may hypothetically rely on non-writability of active connection,
58     ...    workaround is applied by opening and closing temporary connection.
59     ...    Unfortunately this will fail if run on Jython and there is no SSH server
60     ...    running on localhost, port 22 but there is nothing easy that can be done about it.
61     BuiltIn.Run Keyword And Return If    ${connection_index} is not None    SSHLibrary.Switch Connection    ${connection_index}
62     # The background connection is still current, bury it.
63     SSHLibrary.Open Connection    127.0.0.1
64     SSHLibrary.Close Connection
65
66 Run_Keyword_Preserve_Connection
67     [Arguments]    ${keyword_name}    @{args}    &{kwargs}
68     [Documentation]    Store current connection index, run keyword returning its result, restore connection in teardown.
69     ...    Note that in order to avoid "got positional argument after named arguments", it is safer to use positional (not named) arguments on call.
70     ${current_connection}=    SSHLibrary.Get_Connection
71     BuiltIn.Run_Keyword_And_Return    ${keyword_name}    @{args}    &{kwargs}
72     # Resource name has to be prepended, as KarafKeywords still contains a redirect.
73     [Teardown]    SSHKeywords.Restore_Current_SSH_Connection_From_Index    ${current_connection.index}
74
75 Run_Keyword_With_Ssh
76     [Arguments]    ${ip_address}    ${keyword_name}    @{args}    &{kwargs}
77     [Documentation]    Open temporary connection to given IP address, run keyword, close connection, restore previously active connection, return result.
78     Run_Keyword_Preserve_Connection    Run_Unsafely_Keyword_Over_Temporary_Odl_Session    ${ip_address}    ${keyword_name}    @{args}    &{kwargs}
79
80 Run_Unsafely_Keyword_Over_Temporary_Odl_Session
81     [Arguments]    ${ip_address}    ${keyword_name}    @{args}    &{kwargs}
82     [Documentation]    Open connection to given IP address, run keyword, close connection, return result.
83     ...    This is unsafe in the sense that previously active session will be switched out off, but safe in the sense only the temporary connection is closed.
84     Open_Connection_To_ODL_System    ${ip_address}
85     # Not using Teardown, to avoid a call to close if the previous line fails.
86     ${status}    ${result} =    BuiltIn.Run_Keyword_And_Ignore_Error    ${keyword_name}    @{args}    &{kwargs}
87     SSHLibrary.Close_Connection
88     BuiltIn.Return_From_Keyword_If    "${status}" == "PASS"    ${result}
89     BuiltIn.Fail    ${result}
90
91 Log_Command_Results
92     [Arguments]    ${stdout}    ${stderr}    ${rc}
93     [Documentation]    Log everything returned by SSHLibrary.Execute_Command
94     BuiltIn.Log    ${stdout}
95     BuiltIn.Log    ${stderr}
96     BuiltIn.Log    ${rc}
97
98 Execute_Command_Passes
99     [Arguments]    ${command}    ${return_success_only}=True    ${log_on_success}=False    ${log_on_failure}=True    ${stderr_must_be_empty}=False
100     [Documentation]    Execute command via the active SSH connection. For success, rc has to be zero and optionally stderr has to be empty.
101     ...    Log everything, depending on arguments and success. Return either success string or stdout.
102     ...    TODO: Do we want to support customizing return values the same way as SSHLibrary.Execute_Command does?
103     ${stdout}    ${stderr}    ${rc} =    SSHLibrary.Execute_Command    ${command}    return_stderr=True    return_rc=True
104     ${emptiness_status}    ${result} =    BuiltIn.Run_Keyword_And_Ignore_Error    BuiltIn.Should_Be_Empty    ${stderr}
105     ${success} =    BuiltIn.Set_Variable_If    (${rc} == 0) and (("${emptiness_status}" == "PASS") or not ${stderr_must_be_empty})    True    False
106     BuiltIn.Run_Keyword_If    (${log_on_success} and ${success}) or (${log_on_failure} and not ${success})    Log_Command_Results    ${stdout}    ${stderr}    ${rc}
107     BuiltIn.Return_From_Keyword_If    ${return_success_only}    ${success}
108     BuiltIn.Return_From_Keyword_If    ${success}    ${stdout}
109     BuiltIn.Fail    Got rc: ${rc} or stderr was not empty: ${stderr}
110
111 Execute_Command_Should_Pass
112     [Arguments]    ${command}    ${log_on_success}=True    ${log_on_failure}=True    ${stderr_must_be_empty}=False
113     [Documentation]    A wrapper for Execute_Command_Passes with return_success_only=False
114     ...    Also, log_on_success defaults to True (but is customizable, unlike return_success_only)..
115     BuiltIn.Run_Keyword_And_Return    Execute_Command_Passes    ${command}    return_success_only=False    log_on_success=${log_on_success}    log_on_failure=${log_on_failure}    stderr_must_be_empty=${stderr_must_be_empty}
116
117 Execute_Command_At_Path_Should_Pass
118     [Arguments]    ${command}    ${path}=None    ${log_on_success}=True    ${log_on_failure}=True    ${stderr_must_be_empty}=False
119     [Documentation]    A keyword similar to Execute_Command_Should_Pass which performs "cd" to ${path} before executing the ${command}.
120     ...    This is useful when rewriting bash scripts, as series of SSHLibrary.Execute_Command do not share current working directory.
121     ...    TODO: Perhaps a Keyword which sets up environment variables would be useful as well.
122     ${cd_and_command} =    BuiltIn.Set_Variable    cd '${path}' && ${command}
123     BuiltIn.Run_Keyword_And_Return    Execute_Command_Passes    ${cd_and_command}    return_success_only=False    log_on_success=${log_on_success}    log_on_failure=${log_on_failure}    stderr_must_be_empty=${stderr_must_be_empty}
124
125 Set_Cwd
126     [Arguments]    ${path}
127     [Documentation]    Set \${SSHKeywords__current_remote_working_directory} variable to ${path}. If SSH default is desired, use dot.
128     BuiltIn.Set_Suite_Variable    \${SSHKeywords__current_remote_working_directory}    ${path}
129
130 Execute_Command_At_Cwd_Should_Pass
131     [Arguments]    ${command}    ${log_on_success}=True    ${log_on_failure}=True    ${stderr_must_be_empty}=True
132     [Documentation]    Run Execute_Command_At_Path_Should_Pass with previously set CWD as path.
133     BuiltIn.Run_Keyword_And_Return    Execute_Command_At_Path_Should_Pass    command=${command}    path=${SSHKeywords__current_remote_working_directory}    log_on_success=${log_on_success}    log_on_failure=${log_on_failure}    stderr_must_be_empty=${stderr_must_be_empty}
134
135 Require_Python
136     [Documentation]    Verify current SSH connection leads to machine with python working. Fatal fail otherwise.
137     ${passed} =    Execute_Command_Passes    python --help
138     BuiltIn.Return_From_Keyword_If    ${passed}
139     BuiltIn.Fatal_Error    Python is not installed!
140
141 Assure_Library_Ipaddr
142     [Arguments]    ${target_dir}=.
143     [Documentation]    Tests whether ipaddr module is present on ssh-connected machine, Puts ipaddr.py to target_dir if not.
144     ${passed} =    Execute_Command_Passes    bash -c 'cd "${target_dir}" && python -c "import ipaddr"'
145     BuiltIn.Return_From_Keyword_If    ${passed}
146     SSHLibrary.Put_File    ${CURDIR}/BGPCEP/ipaddr.py    ${target_dir}/
147
148 Assure_Library_Counter
149     [Arguments]    ${target_dir}=.
150     [Documentation]    Tests whether Counter is present in collections on ssh-connected machine, Puts Counter.py to workspace if not.
151     ${passed} =    Execute_Command_Passes    bash -c 'cd "${target_dir}" && python -c "from collections import Counter"'
152     # TODO: Move the bash-cd wrapper to separate keyword?
153     BuiltIn.Return_From_Keyword_If    ${passed}
154     SSHLibrary.Put_File    ${CURDIR}/Counter.py    ${target_dir}/
155
156 Count_Port_Occurences
157     [Arguments]    ${port}    ${state}    ${name}
158     [Documentation]    Run 'netstat' on the remote machine and count occurences of given port in the given state connected to process with the given name.
159     ${output} =    SSHLibrary.Execute_Command    ${NETSTAT_COMMAND} 2> /dev/null | grep -E ":${port} .+ ${state} .+${name}" | wc -l
160     [Return]    ${output}
161
162 Virtual_Env_Set_Path
163     [Arguments]    ${venv_path}
164     [Documentation]    Set \${SSHKeywords__current_venv_path} variable to ${venv_path}. Path should be absolute.
165     BuiltIn.Set_Global_Variable    \${SSHKeywords__current_venv_path}    ${venv_path}
166
167 Virtual_Env_Create
168     [Arguments]    ${upgrade_pip}=True
169     [Documentation]    Creates virtual env. If not to use the default name, use Virtual_Env_Set_Path kw. Returns stdout.
170     Execute_Command_At_Cwd_Should_Pass    virtualenv ${SSHKeywords__current_venv_path}
171     BuiltIn.Run_Keyword_And_Return_If    ${upgrade_pip}    Virtual_Env_Run_Cmd_At_Cwd    pip install --upgrade pip    stderr_must_be_empty=False
172
173 Virtual_Env_Create_Python3
174     [Arguments]    ${upgrade_pip}=True
175     [Documentation]    Creates virtual env. If not to use the default name, use Virtual_Env_Set_Path kw. Returns stdout.
176     Execute_Command_At_Cwd_Should_Pass    python3 -m venv ${SSHKeywords__current_venv_path}
177     BuiltIn.Run_Keyword_And_Return_If    ${upgrade_pip}    Virtual_Env_Run_Cmd_At_Cwd    pip install --upgrade pip    stderr_must_be_empty=False
178
179 Virtual_Env_Delete
180     [Documentation]    Deletes a directory with virtual env.
181     Execute_Command_At_Cwd_Should_Pass    rm -rf ${SSHKeywords__current_venv_path}
182
183 Virtual_Env_Run_Cmd_At_Cwd
184     [Arguments]    ${cmd}    ${log_on_success}=True    ${log_on_failure}=True    ${stderr_must_be_empty}=True
185     [Documentation]    Runs given command within activated virtual env and returns stdout.
186     BuiltIn.Run_Keyword_And_Return    Execute_Command_At_Cwd_Should_Pass    source ${SSHKeywords__current_venv_path}/bin/activate; ${cmd}; deactivate    log_on_success=${log_on_success}    log_on_failure=${log_on_failure}    stderr_must_be_empty=${stderr_must_be_empty}
187
188 Virtual_Env_Install_Package
189     [Arguments]    ${package}
190     [Documentation]    Installs python package into virtual env. Use with version if needed (e.g. exabgp==3.4.16). Returns stdout.
191     BuiltIn.Run_Keyword_And_Return    Virtual_Env_Run_Cmd_At_Cwd    pip install ${package}    stderr_must_be_empty=False
192
193 Virtual_Env_Uninstall_Package
194     [Arguments]    ${package}
195     [Documentation]    Uninstalls python package from virtual env and returns stdout.
196     BuiltIn.Run_Keyword_And_Return    Virtual_Env_Run_Cmd_At_Cwd    pip uninstall -y ${package}    stderr_must_be_empty=False
197
198 Virtual_Env_Freeze
199     [Documentation]    Shows installed packages within the returned stdout.
200     BuiltIn.Run_Keyword_And_Return    Virtual_Env_Run_Cmd_At_Cwd    pip freeze --all    stderr_must_be_empty=False
201
202 Virtual_Env_Activate_On_Current_Session
203     [Arguments]    ${log_output}=${False}
204     [Documentation]    Activates virtual environment. To run anything in the env activated this way you should use SSHLibrary.Write and Read commands.
205     SSHLibrary.Write    source ${SSHKeywords__current_venv_path}/bin/activate
206     ${output}=    SSHLibrary.Read_Until_Prompt
207     BuiltIn.Run_Keyword_If    ${log_output}==${True}    BuiltIn.Log    ${output}
208
209 Virtual_Env_Deactivate_On_Current_Session
210     [Arguments]    ${log_output}=${False}
211     [Documentation]    Deactivates virtual environment.
212     SSHLibrary.Write    deactivate
213     ${output}=    SSHLibrary.Read_Until_Prompt
214     BuiltIn.Run_Keyword_If    ${log_output}==${True}    BuiltIn.Log    ${output}
215
216 Unsafe_Copy_File_To_Remote_System
217     [Arguments]    ${system}    ${source}    ${destination}=./    ${user}=${DEFAULT_USER}    ${password}=${DEFAULT_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}
218     ...    ${prompt_timeout}=5s
219     [Documentation]    Copy the ${source} file to the ${destination} file on the remote ${system}. The keyword opens and closes a single
220     ...    ssh connection and does not rely on any existing ssh connection that may be open.
221     SSHLibrary.Open_Connection    ${system}    prompt=${prompt}    timeout=${prompt_timeout}
222     Flexible_SSH_Login    ${user}    ${password}
223     SSHLibrary.Put_File    ${source}    ${destination}
224     SSHLibrary.Close Connection
225
226 Copy_File_To_Remote_System
227     [Arguments]    ${system}    ${source}    ${destination}=./    ${user}=${DEFAULT_USER}    ${password}=${DEFAULT_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}
228     ...    ${prompt_timeout}=5s
229     [Documentation]    Copy the ${source} file to the ${destination} file on the remote ${system}. Any pre-existing active
230     ...    ssh connection will be retained.
231     SSHKeywords.Run_Keyword_Preserve_Connection    SSHKeywords.Unsafe_Copy_File_To_Remote_System    ${system}    ${source}    ${destination}    ${user}    ${password}
232     ...    ${prompt}    ${prompt_timeout}
233
234 Copy_File_To_Odl_System
235     [Arguments]    ${system}    ${source}    ${destination}=./
236     [Documentation]    Wrapper keyword to make it easier to copy a file to an ODL specific system
237     SSHKeywords.Copy_File_To_Remote_System    ${system}    ${source}    ${destination}    ${ODL_SYSTEM_USER}    ${ODL_SYSTEM_PASSWORD}    ${ODL_SYSTEM_PROMPT}
238
239 Copy_File_To_Tools_System
240     [Arguments]    ${system}    ${source}    ${destination}=./
241     [Documentation]    Wrapper keyword to make it easier to copy a file to an Tools specific system
242     SSHKeywords.Copy_File_To_Remote_System    ${system}    ${source}    ${destination}    ${TOOLS_SYSTEM_USER}    ${TOOLS_SYSTEM_PASSWORD}    ${TOOLS_SYSTEM_PROMPT}
243
244 Flexible_SSH_Login
245     [Arguments]    ${user}    ${password}=${EMPTY}    ${delay}=0.5s
246     [Documentation]    On active SSH session: if given non-empty password, do Login, else do Login With Public Key.
247     ${pwd_length} =    BuiltIn.Get Length    ${password}
248     # ${pwd_length} is guaranteed to be an integer, so we are safe to evaluate it as Python expression.
249     BuiltIn.Run Keyword And Return If    ${pwd_length} > 0    SSHLibrary.Login    ${user}    ${password}    delay=${delay}
250     BuiltIn.Run Keyword And Return    SSHLibrary.Login With Public Key    ${user}    ${USER_HOME}/.ssh/${SSH_KEY}    ${KEYFILE_PASS}    delay=${delay}
251
252 Flexible_Mininet_Login
253     [Arguments]    ${user}=${TOOLS_SYSTEM_USER}    ${password}=${TOOLS_SYSTEM_PASSWORD}    ${delay}=0.5s
254     [Documentation]    Call Flexible SSH Login, but with default values suitable for Mininet machine.
255     BuiltIn.Run Keyword And Return    Flexible SSH Login    user=${user}    password=${password}    delay=${delay}
256
257 Flexible_Controller_Login
258     [Arguments]    ${user}=${ODL_SYSTEM_USER}    ${password}=${ODL_SYSTEM_PASSWORD}    ${delay}=0.5s
259     [Documentation]    Call Flexible SSH Login, but with default values suitable for Controller machine.
260     BuiltIn.Run Keyword And Return    Flexible SSH Login    user=${user}    password=${password}    delay=${delay}
261
262 Move_File_To_Remote_System
263     [Arguments]    ${system}    ${source}    ${destination}=./    ${user}=${DEFAULT_USER}    ${password}=${DEFAULT_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}
264     ...    ${prompt_timeout}=5s
265     [Documentation]    Moves the ${source} file to the ${destination} file on the remote ${system}. Any pre-existing active
266     ...    ssh connection will be retained.
267     SSHKeywords.Run_Keyword_Preserve_Connection    Unsafe_Move_File_To_Remote_System    ${system}    ${source}    ${destination}    ${user}    ${password}
268     ...    ${prompt}    ${prompt_timeout}
269
270 Unsafe_Move_File_To_Remote_System
271     [Arguments]    ${system}    ${source}    ${destination}=./    ${user}=${DEFAULT_USER}    ${password}=${DEFAULT_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}
272     ...    ${prompt_timeout}=5s
273     [Documentation]    Moves the ${source} file to the ${destination} file on the remote ${system}. The keyword opens and closes a single
274     ...    ssh connection and does not rely on any existing ssh connection that may be open.
275     SSHLibrary.Open_Connection    ${system}    prompt=${prompt}    timeout=${prompt_timeout}
276     Flexible_SSH_Login    ${user}    ${password}
277     SSHLibrary.Put File    ${source}    ${destination}
278     OperatingSystem.Remove File    ${source}
279     SSHLibrary.Close Connection