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