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