System test for Yangtools
[integration/test.git] / csit / libraries / RemoteBash.robot
diff --git a/csit/libraries/RemoteBash.robot b/csit/libraries/RemoteBash.robot
new file mode 100644 (file)
index 0000000..9703bb3
--- /dev/null
@@ -0,0 +1,100 @@
+*** Settings ***
+Documentation     Resource for managing bash execution when SSHLibrary.Execute_Command is not enough.
+...
+...               Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
+...
+...               This program and the accompanying materials are made available under the
+...               terms of the Eclipse Public License v1.0 which accompanies this distribution,
+...               and is available at http://www.eclipse.org/legal/epl-v10.html
+...
+...
+...               There are many test tools that need to be started from bash,
+...               and then either waited upon or aborted.
+...               Typical hurdles are usage of virtualenv or preventing idle SSH sessions from closing down.
+...               This Resource contains keywords specifically for these situations,
+...               in order to avoid SSHKeywords growing too big.
+...
+...               Each keyword assumes There is a SSH session already esteablished and active,
+...               with properties such as timeout already configured.
+...               No keyword should close or switch away from that session,
+...               but the configured timeout may be changed if requested.
+...
+...               TODO: Backport improvements from project-specific Resources,
+...               for example logging to generated filename from NetconfKeywords and NexusKeywords.
+Library           SSHLibrary
+Resource          ${CURDIR}/SSHKeywords.robot
+
+*** Keywords ***
+Write_Bare_Ctrl_C
+    [Documentation]    Construct ctrl+c character and SSH-write it (without endline) to the current SSH connection.
+    ...    Do not read anything yet.
+    ${ctrl_c} =    BuiltIn.Evaluate    chr(int(3))
+    SSHLibrary.Write_Bare    ${ctrl_c}
+
+Write_Bare_Ctrl_D
+    [Documentation]    Construct ctrl+d character and SSH-write it (without endline) to the current SSH connection.
+    ...    Do not read anything yet.
+    ${ctrl_d} =    BuiltIn.Evaluate    chr(int(4))
+    SSHLibrary.Write_Bare    ${ctrl_d}
+
+Flush_Read
+    [Documentation]    Attempt to read excess data (probably just multiple prompts), ignoring failure.
+    ...    Log the data or error message. Return None.
+    ${status}    ${message} =    BuiltIn.Run_Keyword_And_Ignore_Error    SSHLibrary.Read
+    BuiltIn.Log    ${message}
+
+Abort_Execution
+    [Documentation]    Send ctrl+c, read until prompt, Log and return the read text.
+    # TODO: Maybe timeout can be specified, but the tools usually return quickly.
+    Write_Bare_Ctrl_C
+    ${text} =    SSHLibrary.Read_Until_Prompt
+    BuiltIn.Log    ${text}
+    Flush_Read
+    [Return]    ${text}
+
+RemoteBash__Wait_Iteration
+    [Documentation]    Send a newline and wait for prompt. On success, return the text before the prompt.
+    ...    The newline is there to avoid disconnection due to idling.
+    SSHLibrary.Write    ${EMPTY}
+    ${text} =    SSHLibrary.Read_Until_Prompt
+    [Return]    ${text}
+
+Wait_Without_Idle
+    [Arguments]    ${timeout}    ${refresh}=1s
+    [Documentation]    Wait until prompt, while sending newlines to avoid idling.
+    ...    Flush read and return the text before prompt.
+    ${text} =    Wait_Until_Keyword_Succeeds    ${timeout}    ${refresh}    RemoteBash__Wait_Iteration
+    Flush_Read
+    [Return]    ${text}
+
+Invoke_With_Timeout
+    [Arguments]    ${command}    ${timeout}
+    [Documentation]    Enter ${command}, wait until it finishes and return the output.
+    ...    If it does not finish within timeout, abort it and fail.
+    ...    In either case, flush read.
+    # TODO: Total duration is WUKS timeout plus RUP timeout. Should we do some computation?
+    SSHLibrary.Write    ${command}
+    ${text} =    Wait_Without_Idle    ${timeout}
+    [Teardown]    BuiltIn.Run_Keyword_If    "${KEYWORD_STATUS}" != "PASS"    Abort_Execution
+    [Return]    ${text}
+
+RemoteBash__Log_Text_Before_Prompt
+    [Documentation]    Log text gathered by SSHLibrary.Read_Until_Prompt.
+    ...    This needs to be a separate keyword just because how Verify_Tool_Has_Not_Finished_Yet is implemented.
+    ${text} =    SSHLibrary.Read_Until_Prompt
+    BuiltIn.Log    ${text}
+
+Verify_Tool_Has_Not_Finished_Yet
+    [Documentation]    Try to read SSH to see prompt, but expect to see no prompt within SSHLibrary's timeout.
+    ...    Log any text seen, to help debug what happened when the tool exited early.
+    ${status}    ${message} =    BuiltIn.Run_Keyword_And_Ignore_Error    RemoteBash__Log_Text_Before_Prompt
+    BuiltIn.Return_From_Keyword_If    "${status}" == "FAIL"
+    Builtin.Fail    The prompt was seen but it was not expected yet.
+
+Check_Return_Code
+    [Arguments]    ${expected_rc}=0
+    [Documentation]    Get return code of the previous command, fail if it does not match the expectation..
+    SSHLibrary.Write    echo \$?
+    ${rc_and_prompt} =    SSHLibrary.Read_Until_Prompt
+    ${rc} =    String.Fetch_From_Left    ${rc_and_prompt}    ${\n}
+    BuiltIn.Should_Be_Equal_As_Integers    0    ${rc}