Upgrade RF syntax for v3.2 compatibility
[integration/test.git] / csit / libraries / KarafKeywords.robot
index 8bbbd72fb32cb5444e4004439382cfdbd8884bc5..0463c81577d0098c2ef4eabe5f8aef0c4a0f8da3 100644 (file)
@@ -1,9 +1,13 @@
 *** Settings ***
 *** Settings ***
-Documentation     Karaf library. This library is useful to deal with controller Karaf console for ssh sessions in cluster.
-...               Running Setup Karaf Keywords is necessary. If SetupUtils initialization is called, this gets initialized as well.
+Documentation     Karaf library. General utility keywords for interacting with the karaf environment, such as the
+...               karaf console, karaf.log, karaf features, and karaf config files.
+...
+...               This library is useful to deal with controller Karaf console for ssh sessions in cluster.
+...               Running Setup_Karaf_Keywords is necessary. If SetupUtils initialization is called, this gets initialized as well.
 ...               If this gets initialized, ClusterManagement gets initialized as well.
 Library           SSHLibrary
 Library           OperatingSystem
 ...               If this gets initialized, ClusterManagement gets initialized as well.
 Library           SSHLibrary
 Library           OperatingSystem
+Library           ${CURDIR}/netvirt/excepts.py
 Resource          ${CURDIR}/ClusterManagement.robot
 Resource          ${CURDIR}/SSHKeywords.robot
 Variables         ${CURDIR}/../variables/Variables.py
 Resource          ${CURDIR}/ClusterManagement.robot
 Resource          ${CURDIR}/SSHKeywords.robot
 Variables         ${CURDIR}/../variables/Variables.py
@@ -13,30 +17,34 @@ ${WORKSPACE}      /tmp
 ${connection_index_dict}    &{EMPTY}
 
 *** Keywords ***
 ${connection_index_dict}    &{EMPTY}
 
 *** Keywords ***
-Setup Karaf Keywords
+Setup_Karaf_Keywords
+    [Arguments]    ${http_timeout}=${DEFAULT_TIMEOUT_HTTP}
     [Documentation]    Initialize ClusterManagement. Open ssh karaf connections to each ODL.
     [Documentation]    Initialize ClusterManagement. Open ssh karaf connections to each ODL.
-    ClusterManagement.ClusterManagement_Setup
+    ClusterManagement.ClusterManagement_Setup    http_timeout=${http_timeout}
+    ClusterManagement.Run_Bash_Command_On_List_Or_All    iptables -I INPUT -p tcp --dport ${KARAF_SHELL_PORT} -j ACCEPT; iptables-save
     BuiltIn.Comment    First connections to Karaf console may fail, so WUKS is used. TODO: Track as a Bug.
     BuiltIn.Comment    First connections to Karaf console may fail, so WUKS is used. TODO: Track as a Bug.
-    : FOR    ${index}    IN    @{ClusterManagement__member_index_list}
-    \    BuiltIn.Wait_Until_Keyword_Succeeds    10x    0.2s    Open Controller Karaf Console On Background    member_index=${index}
+    FOR    ${index}    IN    @{ClusterManagement__member_index_list}
+        BuiltIn.Run_Keyword_And_Ignore_Error    BuiltIn.Wait_Until_Keyword_Succeeds    3s    1s    Open_Controller_Karaf_Console_On_Background    member_index=${index}
+    END
 
 
-Verify Feature Is Installed
+Verify_Feature_Is_Installed
     [Arguments]    ${feature_name}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}
     [Documentation]    Will Succeed if the given ${feature_name} is found in the output of "feature:list -i"
     [Arguments]    ${feature_name}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}
     [Documentation]    Will Succeed if the given ${feature_name} is found in the output of "feature:list -i"
-    ${output}=    Issue Command On Karaf Console    feature:list -i | grep ${feature_name}    ${controller}    ${karaf_port}
-    Should Contain    ${output}    ${feature_name}
+    ${output} =    Issue_Command_On_Karaf_Console    feature:list -i | grep ${feature_name}    ${controller}    ${karaf_port}
+    BuiltIn.Should_Contain    ${output}    ${feature_name}
     [Return]    ${output}
 
     [Return]    ${output}
 
-Issue Command On Karaf Console
+Issue_Command_On_Karaf_Console
     [Arguments]    ${cmd}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}    ${timeout}=10    ${loglevel}=INFO
     [Documentation]    Will execute the given ${cmd} by ssh'ing to the karaf console running on ${controller}
     ...    Note that this keyword will open&close new SSH connection, without switching back to previously current session.
     [Arguments]    ${cmd}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}    ${timeout}=10    ${loglevel}=INFO
     [Documentation]    Will execute the given ${cmd} by ssh'ing to the karaf console running on ${controller}
     ...    Note that this keyword will open&close new SSH connection, without switching back to previously current session.
-    Open Connection    ${controller}    port=${karaf_port}    prompt=${KARAF_PROMPT}    timeout=${timeout}
-    Login    ${KARAF_USER}    ${KARAF_PASSWORD}    loglevel=${loglevel}
-    Write    ${cmd}
-    ${output}    Read Until    ${KARAF_PROMPT}
-    Close Connection
-    Log    ${output}
+    SSHLibrary.Open_Connection    ${controller}    port=${karaf_port}    prompt=${KARAF_PROMPT_LOGIN}    timeout=${timeout}
+    SSHLibrary.Login    ${KARAF_USER}    ${KARAF_PASSWORD}    loglevel=${loglevel}
+    SSHLibrary.Write    ${cmd}
+    ${output}    SSHLibrary.Read_Until_Regexp    ${KARAF_PROMPT}
+    SSHLibrary.Write    logout
+    SSHLibrary.Close_Connection
+    BuiltIn.Log    ${output}
     [Return]    ${output}
 
 Safe_Issue_Command_On_Karaf_Console
     [Return]    ${output}
 
 Safe_Issue_Command_On_Karaf_Console
@@ -49,146 +57,270 @@ Check For Elements On Karaf Command Output Message
     [Arguments]    ${cmd}    ${elements}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}    ${timeout}=5
     [Documentation]    Will execute the command using Issue Command On Karaf Console then check for the given elements
     ...    in the command output message
     [Arguments]    ${cmd}    ${elements}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}    ${timeout}=5
     [Documentation]    Will execute the command using Issue Command On Karaf Console then check for the given elements
     ...    in the command output message
-    ${output}    Issue Command On Karaf Console    ${cmd}    ${controller}    ${karaf_port}    ${timeout}
-    : FOR    ${i}    IN    @{elements}
-    \    Should Contain    ${output}    ${i}
+    ${output}    Issue_Command_On_Karaf_Console    ${cmd}    ${controller}    ${karaf_port}    ${timeout}
+    FOR    ${i}    IN    @{elements}
+        BuiltIn.Should_Contain    ${output}    ${i}
+    END
 
 
-Verify Bundle Is Installed
+Verify_Bundle_Is_Installed
     [Arguments]    ${bundle_name}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}
     [Documentation]    Will succeed if the given ${bundle name} is present in the output of "bundle:list -s "
     [Arguments]    ${bundle_name}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}
     [Documentation]    Will succeed if the given ${bundle name} is present in the output of "bundle:list -s "
-    ${output}=    Issue Command On Karaf Console    bundle:list -s | grep ${bundle_name}    ${controller}    ${karaf_port}
-    Should Contain    ${output}    ${bundle_name}
+    ${output} =    Issue_Command_On_Karaf_Console    bundle:list -s | grep ${bundle_name}    ${controller}    ${karaf_port}
+    BuiltIn.Should_Contain    ${output}    ${bundle_name}
     [Return]    ${output}
 
     [Return]    ${output}
 
-Verify Bundle Is Not Installed
+Verify_Bundle_Is_Not_Installed
     [Arguments]    ${bundle_name}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}
     [Documentation]    Will succeed if the given ${bundle_name} is NOT found in the output of "bundle:list -s"
     [Arguments]    ${bundle_name}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}
     [Documentation]    Will succeed if the given ${bundle_name} is NOT found in the output of "bundle:list -s"
-    ${output}=    Issue Command On Karaf Console    bundle:list -i | grep ${bundle_name}    ${controller}    ${karaf_port}
-    Should Not Contain    ${output}    ${bundle_name}
+    ${output} =    Issue_Command_On_Karaf_Console    bundle:list -i | grep ${bundle_name}    ${controller}    ${karaf_port}
+    BuiltIn.Should_Not_Contain    ${output}    ${bundle_name}
     [Return]    ${output}
 
     [Return]    ${output}
 
-Check Karaf Log Has Messages
+Check_Karaf_Log_Has_Messages
     [Arguments]    ${filter_string}    @{message_list}
     [Documentation]    Will succeed if the @{messages} are found in \ the output of "log:display"
     [Arguments]    ${filter_string}    @{message_list}
     [Documentation]    Will succeed if the @{messages} are found in \ the output of "log:display"
-    ${output}=    Issue Command On Karaf Console    log:display | grep ${filter_string}
-    : FOR    ${message}    IN    @{message_list}
-    \    Should Contain    ${output}    ${message}
+    ${output} =    Issue_Command_On_Karaf_Console    log:display | grep ${filter_string}
+    FOR    ${message}    IN    @{message_list}
+        BuiltIn.Should_Contain    ${output}    ${message}
+    END
     [Return]    ${output}
 
     [Return]    ${output}
 
-Install a Feature
+Check_Karaf_Log_Message_Count
+    [Arguments]    ${message}    ${count}    ${use_console}=False
+    [Documentation]    Verifies that the ${message} exists specified number of times in
+    ...    karaf console log or Karaf Log Folder based on the arg ${use_console}.
+    Run Keyword If    ${use_console} == False    Check_Karaf_Log_File    ${message}    ${count}
+    ...    ELSE    Check_Karaf_Log_From_Console    ${message}    ${count}
+
+Check_Karaf_Log_From_Console
+    [Arguments]    ${message}    ${count}
+    [Documentation]    Verifies that the ${message} exists in the Karaf Console log:display and checks
+    ...    that it appears ${count} number of times
+    ${output} =    Issue_Command_On_Karaf_Console    log:display | grep ${message} | wc -l
+    ${line} =    Get Line    ${output}    0
+    ${stripped} =    Strip String    ${line}
+    Should Be Equal As Strings    ${stripped}    ${count}
+
+Check_Karaf_Log_File
+    [Arguments]    ${message}    ${count}
+    [Documentation]    Verifies that the ${message} exists in the Karaf Log Folder and checks
+    ...    that it appears ${count} number of times
+    ${output}    Run Command On Controller    ${ODL_SYSTEM_IP}    grep -o ${message} ${WORKSPACE}/${BUNDLEFOLDER}/data/log/* | wc -l
+    Should Be Equal As Strings    ${output}    ${count}
+
+Install_A_Feature
     [Arguments]    ${feature_name}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}    ${timeout}=180
     [Documentation]    Will Install the given ${feature_name}
     [Arguments]    ${feature_name}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}    ${timeout}=180
     [Documentation]    Will Install the given ${feature_name}
-    Log    ${timeout}
-    ${output}=    Issue Command On Karaf Console    feature:install ${feature_name}    ${controller}    ${karaf_port}    ${timeout}
-    Log    ${output}
+    BuiltIn.Log    ${timeout}
+    ${output} =    Issue_Command_On_Karaf_Console    feature:install ${feature_name}    ${controller}    ${karaf_port}    ${timeout}
+    BuiltIn.Log    ${output}
     [Return]    ${output}
 
     [Return]    ${output}
 
-Install a Feature Using Active Connection
+Install_A_Feature_Using_Active_Connection
     [Arguments]    ${feature_name}
     [Documentation]    Will Install the given ${feature_name} using active connection
     [Arguments]    ${feature_name}
     [Documentation]    Will Install the given ${feature_name} using active connection
-    ${cmd}=    BuiltIn.Set_Variable    feature:install ${feature_name}
-    Write    ${cmd}
-    ${output}    SSHLibrary.Read_Until    ${KARAF_PROMPT}
-    Log    ${output}
+    ${cmd} =    BuiltIn.Set_Variable    feature:install ${feature_name}
+    SSHLibrary.Write    ${cmd}
+    ${output}    SSHLibrary.Read_Until_Regexp    ${KARAF_PROMPT}
+    BuiltIn.Log    ${output}
     [Return]    ${output}
 
     [Return]    ${output}
 
-Uninstall a Feature
+Uninstall_A_Feature
     [Arguments]    ${feature_name}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}    ${timeout}=180
     [Documentation]    Will UnInstall the given ${feature_name}
     [Arguments]    ${feature_name}    ${controller}=${ODL_SYSTEM_IP}    ${karaf_port}=${KARAF_SHELL_PORT}    ${timeout}=180
     [Documentation]    Will UnInstall the given ${feature_name}
-    ${output}=    Issue Command On Karaf Console    feature:uninstall ${feature_name}    ${controller}    ${karaf_port}    ${timeout}
-    Log    ${output}
+    ${output} =    Issue_Command_On_Karaf_Console    feature:uninstall ${feature_name}    ${controller}    ${karaf_port}    ${timeout}
+    BuiltIn.Log    ${output}
     [Return]    ${output}
 
     [Return]    ${output}
 
-Open Controller Karaf Console On Background
+Open_Controller_Karaf_Console_On_Background
     [Arguments]    ${member_index}=${1}    ${timeout}=10    ${loglevel}=INFO
     [Documentation]    If there is a stored ssh connection index of connection to the controller's karaf console for ${member_index},
     ...    close the previous connection. In any case create a new connection
     ...    to karaf console for ${member_index}, set correct prompt set and login to karaf console.
     ...    Store connection index for ${member_index} and restore the previous active connection.
     [Arguments]    ${member_index}=${1}    ${timeout}=10    ${loglevel}=INFO
     [Documentation]    If there is a stored ssh connection index of connection to the controller's karaf console for ${member_index},
     ...    close the previous connection. In any case create a new connection
     ...    to karaf console for ${member_index}, set correct prompt set and login to karaf console.
     ...    Store connection index for ${member_index} and restore the previous active connection.
-    ${current_ssh_connection_object}=    SSHLibrary.Get Connection
+    ${current_ssh_connection_object}=    SSHLibrary.Get_Connection
     BuiltIn.Log    ${connection_index_dict}
     BuiltIn.Log    ${member_index}
     BuiltIn.Log    ${connection_index_dict}
     BuiltIn.Log    ${member_index}
-    ${status}    ${old_connection_index} =    BuiltIn.Run Keyword And Ignore Error    Get From Dictionary    ${connection_index_dict}    ${member_index}
-    BuiltIn.Run Keyword If    '${status}'=='PASS'    BuiltIn.Run Keywords    SSHLibrary.Switch Connection    ${old_connection_index}
-    ...    AND    SSHLibrary.Close Connection
-    ${odl_ip}=    ClusterManagement.Resolve_IP_Address_For_Member    ${member_index}
-    SSHLibrary.Open Connection    ${odl_ip}    port=${KARAF_SHELL_PORT}    prompt=${KARAF_DETAILED_PROMPT}    timeout=${timeout}
-    ${karaf_connection_object}=    SSHLibrary.Get Connection
-    Collections.Set To Dictionary    ${connection_index_dict}    ${member_index}    ${karaf_connection_object.index}
+    ${status}    ${old_connection_index} =    BuiltIn.Run_Keyword_And_Ignore_Error    Get From Dictionary    ${connection_index_dict}    ${member_index}
+    BuiltIn.Run_Keyword_If    '${status}'=='PASS'    BuiltIn.Run_Keywords    SSHLibrary.Switch_Connection    ${old_connection_index}
+    ...    AND    BuiltIn.Run_Keyword_And_Ignore_Error    SSHLibrary.Write    logout
+    ...    AND    BuiltIn.Run_Keyword_And_Ignore_Error    SSHLibrary.Close_Connection
+    ${odl_ip} =    ClusterManagement.Resolve_IP_Address_For_Member    ${member_index}
+    SSHLibrary.Open_Connection    ${odl_ip}    port=${KARAF_SHELL_PORT}    prompt=${KARAF_PROMPT_LOGIN}    timeout=${timeout}
+    ${karaf_connection_object} =    SSHLibrary.Get_Connection
+    Collections.Set_To_Dictionary    ${connection_index_dict}    ${member_index}    ${karaf_connection_object.index}
     SSHLibrary.Login    ${KARAF_USER}    ${KARAF_PASSWORD}    loglevel=${loglevel}
     SSHLibrary.Login    ${KARAF_USER}    ${KARAF_PASSWORD}    loglevel=${loglevel}
-    [Teardown]    SSHKeywords.Restore Current SSH Connection From Index    ${current_ssh_connection_object.index}
+    [Teardown]    SSHKeywords.Restore_Current_Ssh_Connection_From_Index    ${current_ssh_connection_object.index}
 
 
-Open Controller Karaf Console With Timeout
+Open_Controller_Karaf_Console_With_Timeout
     [Arguments]    ${member_index}=${1}    ${timeout}=3s
     [Documentation]    Open new connection to karaf console for member index with specified timeout.
     BuiltIn.Log    ${member_index}
     [Arguments]    ${member_index}=${1}    ${timeout}=3s
     [Documentation]    Open new connection to karaf console for member index with specified timeout.
     BuiltIn.Log    ${member_index}
-    ${odl_ip}=    ClusterManagement.Resolve_IP_Address_For_Member    ${member_index}
-    SSHLibrary.Open Connection    ${odl_ip}    port=${KARAF_SHELL_PORT}    prompt=${KARAF_DETAILED_PROMPT}    timeout=${timeout}
+    ${odl_ip} =    ClusterManagement.Resolve_IP_Address_For_Member    ${member_index}
+    SSHLibrary.Open_Connection    ${odl_ip}    port=${KARAF_SHELL_PORT}    prompt=${KARAF_PROMPT_LOGIN}    timeout=${timeout}
     SSHLibrary.Login    ${KARAF_USER}    ${KARAF_PASSWORD}
 
     SSHLibrary.Login    ${KARAF_USER}    ${KARAF_PASSWORD}
 
-Configure Timeout For Karaf Console
+Configure_Timeout_For_Karaf_Console
     [Arguments]    ${timeout}    ${member_index_list}=${EMPTY}
     [Documentation]    Configure a different timeout for each Karaf console.
     [Arguments]    ${timeout}    ${member_index_list}=${EMPTY}
     [Documentation]    Configure a different timeout for each Karaf console.
-    ${index_list} =    ClusterManagement.List Indices Or All    given_list=${member_index_list}
-    ${current_connection_object}=    SSHLibrary.Get Connection
-    : FOR    ${member_index}    IN    @{index_list}    # usually: 1, 2, 3
-    \    ${karaf_connection_index}=    Collections.Get From Dictionary    ${connection_index_dict}    ${member_index}
-    \    SSHLibrary.Switch Connection    ${karaf_connection_index}
-    \    SSHLibrary.Set_Client_Configuration    timeout=${timeout}
-    [Teardown]    SSHKeywords.Restore Current SSH Connection From Index    ${current_connection_object.index}
-
-Execute Controller Karaf Command On Background
+    ${index_list} =    ClusterManagement.List_Indices_Or_All    given_list=${member_index_list}
+    ${current_connection_object} =    SSHLibrary.Get_Connection
+    FOR    ${member_index}    IN    @{index_list}    # usually: 1, 2, 3
+        ${karaf_connection_index} =    Collections.Get_From_Dictionary    ${connection_index_dict}    ${member_index}
+        SSHLibrary.Switch_Connection    ${karaf_connection_index}
+        SSHLibrary.Set_Client_Configuration    timeout=${timeout}
+    END
+    [Teardown]    SSHKeywords.Restore_Current_Ssh_Connection_From_Index    ${current_connection_object.index}
+
+Execute_Controller_Karaf_Command_On_Background
     [Arguments]    ${command}    ${member_index}=${1}
     [Documentation]    Send command to karaf without affecting current SSH connection. Read, log and return response.
     [Arguments]    ${command}    ${member_index}=${1}
     [Documentation]    Send command to karaf without affecting current SSH connection. Read, log and return response.
-    ${karaf_connection_index}=    Collections.Get From Dictionary    ${connection_index_dict}    ${member_index}
-    ${current_connection_index}=    SSHLibrary.Switch Connection    ${karaf_connection_index}
-    ${status_write}    ${message_write}=    BuiltIn.Run Keyword And Ignore Error    SSHLibrary.Write    ${command}
-    ${status_wait}    ${message_wait}=    BuiltIn.Run Keyword And Ignore Error    SSHLibrary.Read Until Prompt
+    ${karaf_connection_index} =    Collections.Get_From_Dictionary    ${connection_index_dict}    ${member_index}
+    ${current_connection_index} =    SSHLibrary.Switch_Connection    ${karaf_connection_index}
+    ${status_write}    ${message_write} =    BuiltIn.Run_Keyword_And_Ignore_Error    SSHLibrary.Write    ${command}
+    ${status_wait}    ${message_wait} =    BuiltIn.Run_Keyword_And_Ignore_Error    SSHLibrary.Read_Until_Regexp    ${KARAF_PROMPT}
     BuiltIn.Run Keyword If    '${status_write}' != 'PASS'    BuiltIn.Fail    Failed to send the command: ${command}
     BuiltIn.Log    ${message_wait}
     BuiltIn.Run Keyword If    '${status_write}' != 'PASS'    BuiltIn.Fail    Failed to send the command: ${command}
     BuiltIn.Log    ${message_wait}
-    BuiltIn.Run Keyword If    '${status_wait}' != 'PASS'    BuiltIn.Fail    Failed to see prompt after sending the command: ${command}
-    [Teardown]    SSHKeywords.Restore Current SSH Connection From Index    ${current_connection_index}
+    BuiltIn.Run_Keyword_If    '${status_wait}' != 'PASS'    BuiltIn.Fail    Failed to see prompt after sending the command: ${command}
+    [Teardown]    SSHKeywords.Restore_Current_Ssh_Connection_From_Index    ${current_connection_index}
     [Return]    ${message_wait}
 
     [Return]    ${message_wait}
 
-Execute Controller Karaf Command With Retry On Background
+Execute_Controller_Karaf_Command_With_Retry_On_Background
     [Arguments]    ${command}    ${member_index}=${1}
     [Documentation]    Attemp to send command to karaf for ${member_index}, if fail then open connection and try again.
     [Arguments]    ${command}    ${member_index}=${1}
     [Documentation]    Attemp to send command to karaf for ${member_index}, if fail then open connection and try again.
-    ${status}    ${message}=    BuiltIn.Run Keyword And Ignore Error    Execute Controller Karaf Command On Background    ${command}    ${member_index}
+    ${status}    ${message} =    BuiltIn.Run_Keyword_And_Ignore_Error    Execute_Controller_Karaf_Command_On_Background    ${command}    ${member_index}
     BuiltIn.Return_From_Keyword_If    '${status}' == 'PASS'    ${message}
     # TODO: Verify this does not leak connections indices.
     BuiltIn.Return_From_Keyword_If    '${status}' == 'PASS'    ${message}
     # TODO: Verify this does not leak connections indices.
-    Open Controller Karaf Console On Background    ${member_index}
-    ${message}=    Execute Controller Karaf Command On Background    ${command}    ${member_index}
+    Open_Controller_Karaf_Console_On_Background    ${member_index}
+    ${message} =    Execute_Controller_Karaf_Command_On_Background    ${command}    ${member_index}
     [Return]    ${message}
 
     [Return]    ${message}
 
-Log Message To Controller Karaf
+Log_Message_To_Controller_Karaf
     [Arguments]    ${message}    ${member_index_list}=${EMPTY}    ${tolerate_failure}=True
     [Documentation]    Make sure this resource is initialized. Send a message into the controller's karaf log file on every node listed (or all).
     ...    By default, failure while processing a node is silently ignored, unless ${tolerate_failure} is False.
     [Arguments]    ${message}    ${member_index_list}=${EMPTY}    ${tolerate_failure}=True
     [Documentation]    Make sure this resource is initialized. Send a message into the controller's karaf log file on every node listed (or all).
     ...    By default, failure while processing a node is silently ignored, unless ${tolerate_failure} is False.
-    ${index_list} =    ClusterManagement.List Indices Or All    given_list=${member_index_list}
-    : FOR    ${index}    IN    @{index_list}    # usually: 1, 2, 3.
-    \    ${status}    ${output}=    BuiltIn.Run Keyword And Ignore Error    Execute Controller Karaf Command With Retry On Background    log:log "ROBOT MESSAGE: ${message}"    member_index=${index}
-    \    BuiltIn.Run_Keyword_Unless    ${tolerate_failure} or "${status}" == "PASS"    BuiltIn.Fail    ${output}
+    ${index_list} =    ClusterManagement.List_Indices_Or_All    given_list=${member_index_list}
+    FOR    ${index}    IN    @{index_list}    # usually: 1, 2, 3.
+        ${status}    ${output} =    BuiltIn.Run_Keyword_And_Ignore_Error    Execute_Controller_Karaf_Command_With_Retry_On_Background    log:log "ROBOT MESSAGE: ${message}"    member_index=${index}
+        BuiltIn.Run_Keyword_Unless    ${tolerate_failure} or "${status}" == "PASS"    BuiltIn.Fail    ${output}
+    END
 
 
-Log Test Suite Start To Controller Karaf
+Log_Test_Suite_Start_To_Controller_Karaf
     [Arguments]    ${member_index_list}=${EMPTY}
     [Documentation]    Log suite name to karaf log, useful in suite setup.
     [Arguments]    ${member_index_list}=${EMPTY}
     [Documentation]    Log suite name to karaf log, useful in suite setup.
-    Log Message To Controller Karaf    Starting suite ${SUITE_SOURCE}    ${member_index_list}
+    Log_Message_To_Controller_Karaf    Starting suite ${SUITE_SOURCE}    ${member_index_list}
 
 
-Log Testcase Start To Controller Karaf
+Log_Testcase_Start_To_Controller_Karaf
     [Arguments]    ${member_index_list}=${EMPTY}
     [Documentation]    Log test case name to karaf log, useful in test case setup.
     [Arguments]    ${member_index_list}=${EMPTY}
     [Documentation]    Log test case name to karaf log, useful in test case setup.
-    Log Message To Controller Karaf    Starting test ${TEST_NAME}    ${member_index_list}
+    Log_Message_To_Controller_Karaf    Starting test ${SUITE_NAME}.${TEST_NAME}    ${member_index_list}
 
 
-Set Bgpcep Log Levels
+Set_Bgpcep_Log_Levels
     [Arguments]    ${bgpcep_level}=${DEFAULT_BGPCEP_LOG_LEVEL}    ${protocol_level}=${DEFAULT_PROTOCOL_LOG_LEVEL}    ${member_index_list}=${EMPTY}
     [Documentation]    Assuming OCKCOB was used, set logging level on bgpcep and protocol loggers without affecting current SSH session.
     # FIXME: Move to appropriate Resource
     [Arguments]    ${bgpcep_level}=${DEFAULT_BGPCEP_LOG_LEVEL}    ${protocol_level}=${DEFAULT_PROTOCOL_LOG_LEVEL}    ${member_index_list}=${EMPTY}
     [Documentation]    Assuming OCKCOB was used, set logging level on bgpcep and protocol loggers without affecting current SSH session.
     # FIXME: Move to appropriate Resource
-    ${index_list} =    ClusterManagement.List Indices Or All    given_list=${member_index_list}
-    : FOR    ${index}    IN    @{index_list}    # usually: 1, 2, 3.
-    \    Execute Controller Karaf Command On Background    log:set ${bgpcep_level} org.opendaylight.bgpcep    member_index=${index}
-    \    Execute Controller Karaf Command On Background    log:set ${protocol_level} org.opendaylight.protocol    member_index=${index}
+    ${index_list} =    ClusterManagement.List_Indices_Or_All    given_list=${member_index_list}
+    FOR    ${index}    IN    @{index_list}    # usually: 1, 2, 3.
+        Execute_Controller_Karaf_Command_On_Background    log:set ${bgpcep_level} org.opendaylight.bgpcep    member_index=${index}
+        Execute_Controller_Karaf_Command_On_Background    log:set ${protocol_level} org.opendaylight.protocol    member_index=${index}
+    END
+
+Get Karaf Log Lines From Test Start
+    [Arguments]    ${ip}    ${test_name}    ${cmd}    ${user}=${ODL_SYSTEM_USER}    ${password}=${ODL_SYSTEM_PASSWORD}    ${prompt}=${ODL_SYSTEM_PROMPT}
+    ...    ${log_file}=${KARAF_LOG}
+    [Documentation]    Scrapes all log messages that match regexp ${type} which fall after a point given by a log message that
+    ...    contains ${test_name}. This is useful if your test cases are marking karaf.log with a message indicating when
+    ...    that test case has started; such that you can easily pull out any extra log messsages to parse/log/etc in the
+    ...    test logic itself. For example, you can grab all ERRORS that occur during your test case.
+    ${output} =    Run Command On Controller    ${ip}    ${cmd}    ${user}    ${password}    ${prompt}
+    @{log_lines} =    Split String    ${output}    ${\n}
+    [Return]    ${log_lines}
+
+Fail If Exceptions Found During Test
+    [Arguments]    ${test_name}    ${log_file}=${KARAF_LOG}    ${fail}=False
+    [Documentation]    Create a failure if an Exception is found in the karaf.log that has not been whitelisted.
+    ...    Will work for single controller jobs as well as 3node cluster jobs
+    FOR    ${i}    IN RANGE    1    ${NUM_ODL_SYSTEM} + 1
+        ${cmd} =    Set Variable    sed '1,/ROBOT MESSAGE: Starting test ${test_name}/d' ${log_file}
+        ${output} =    Get Karaf Log Lines From Test Start    ${ODL_SYSTEM_${i}_IP}    ${test_name}    ${cmd}
+        ${exlist}    ${matchlist} =    Verify Exceptions    ${output}
+        Write Exceptions Map To File    ${SUITE_NAME}.${TEST_NAME}    /tmp/odl${i}_exceptions.txt
+        ${listlength} =    BuiltIn.Get Length    ${exlist}
+        BuiltIn.Run Keyword If    "${fail}"=="True" and ${listlength} != 0    Log And Fail Exceptions    ${exlist}    ${listlength}
+        ...    ELSE    Collections.Log List    ${matchlist}
+    END
+
+Log And Fail Exceptions
+    [Arguments]    ${exlist}    ${listlength}
+    [Documentation]    Print the list of failed exceptions and fail the test
+    Collections.Log List    ${exlist}
+    ${exstr} =    BuiltIn.Catenate    ${exlist}
+    BuiltIn.Fail    New exceptions found: ${listlength}\n${exstr}
+
+Get Karaf Log Type From Test Start
+    [Arguments]    ${ip}    ${test_name}    ${type}    ${user}=${ODL_SYSTEM_USER}    ${password}=${ODL_SYSTEM_PASSWORD}    ${prompt}=${ODL_SYSTEM_PROMPT}
+    ...    ${log_file}=${KARAF_LOG}
+    [Documentation]    Scrapes all log messages that match regexp ${type} which fall after a point given by a log message that
+    ...    contains ${test_name}. This is useful if your test cases are marking karaf.log with a message indicating when
+    ...    that test case has started; such that you can easily pull out any extra log messsages to parse/log/etc in the
+    ...    test logic itself. For example, you can grab all ERRORS that occur during your test case.
+    ${cmd}    Set Variable    sed '1,/ROBOT MESSAGE: Starting test ${test_name}/d' ${log_file} | grep '${type}'
+    ${output}    Run Command On Controller    ${ip}    ${cmd}    ${user}    ${password}    ${prompt}
+    [Return]    ${output}
 
 
-Wait For Karaf Log
+Get Karaf Log Types From Test Start
+    [Arguments]    ${ip}    ${test_name}    ${types}    ${user}=${ODL_SYSTEM_USER}    ${password}=${ODL_SYSTEM_PASSWORD}    ${prompt}=${ODL_SYSTEM_PROMPT}
+    ...    ${log_file}=${KARAF_LOG}
+    [Documentation]    A wrapper keyword for "Get Karaf Log Type From Test Start" so that we can parse for multiple types
+    ...    of log messages. For example, we can grab all messages of type WARN and ERROR
+    FOR    ${type}    IN    @{types}
+        Get Karaf Log Type From Test Start    ${ip}    ${test_name}    ${type}    ${user}    ${password}
+        ...    ${prompt}    ${log_file}
+    END
+
+Get Karaf Log Events From Test Start
+    [Arguments]    ${test_name}    ${user}=${ODL_SYSTEM_USER}    ${password}=${ODL_SYSTEM_PASSWORD}    ${prompt}=${ODL_SYSTEM_PROMPT}
+    [Documentation]    Wrapper for the wrapper "Get Karaf Log Types From Test Start" so that we can easily loop over
+    ...    any number of controllers to analyze karaf.log for ERROR, WARN and Exception log messages
+    ${log_types} =    Create List    ERROR    WARN    Exception
+    FOR    ${i}    IN RANGE    1    ${NUM_ODL_SYSTEM} + 1
+        Get Karaf Log Types From Test Start    ${ODL_SYSTEM_${i}_IP}    ${test_name}    ${log_types}
+    END
+
+Fail If Exceptions Found During Test Deprecated
+    [Arguments]    ${test_name}    ${exceptions_white_list}=${EMPTY}
+    [Documentation]    Create a failure if an Exception is found in the karaf.log. Will work for single controller jobs
+    ...    as well as 3node cluster jobs
+    FOR    ${i}    IN RANGE    1    ${NUM_ODL_SYSTEM} + 1
+        Verify Exception Logging In Controller    ${ODL_SYSTEM_${i}_IP}    ${test_name}    ${exceptions_white_list}
+    END
+
+Verify Exception Logging In Controller
+    [Arguments]    ${controller_ip}    ${test_name}    ${exceptions_white_list}
+    [Documentation]    Local keyword to make it easier to loop through N controllers to pull Exceptions from the
+    ...    karaf.log file and validate with "Check Against White List"
+    ${exceptions}=    Get Karaf Log Type From Test Start    ${controller_ip}    ${test_name}    Exception
+    @{log_lines}=    Split String    ${exceptions}    ${\n}
+    ${num_log_entries}    Get Length    ${log_lines}
+    Return From Keyword If    ${num_log_entries} == ${0}    No Exceptions found.
+    FOR    ${log_message}    IN    @{log_lines}
+        Check Against White List    ${log_message}    ${exceptions_white_list}
+    END
+
+Check Against White List
+    [Arguments]    ${exception_line}    ${exceptions_white_list}
+    [Documentation]    As soon as the ${exceptions_line} is found in one of the elements of ${exceptions_white_list}
+    ...    this keyword will exit and give a Pass to the caller. If there is no match, this keyword will end up
+    ...    marking a failure. In the case that no exceptions are found, the caller could end up passing a single
+    ...    empty line as that is what is returned when a grep on karaf.log has no match, so we can safely return
+    ...    in that case as well.
+    Return From Keyword If    "${exception_line}" == ""
+    FOR    ${exception}    IN    @{exceptions_white_list}
+        Return From Keyword If    "${exception}" in "${exception_line}"    Exceptions found, but whitelisted: ${\n}${exception_line}${\n}
+    END
+    Fail    Exceptions Found: ${\n}${exception_line}${\n}
+
+Wait_For_Karaf_Log
     [Arguments]    ${message}    ${timeout}=60    ${member_index}=${1}
     [Documentation]    Read karaf logs until message appear
     # TODO: refactor this keyword to use the new workflow to account for multiple controllers.    Initial work was done
     [Arguments]    ${message}    ${timeout}=60    ${member_index}=${1}
     [Documentation]    Read karaf logs until message appear
     # TODO: refactor this keyword to use the new workflow to account for multiple controllers.    Initial work was done
@@ -196,9 +328,29 @@ Wait For Karaf Log
     # however, the consumers of this keyword were breaking after that change.    Initial theory is that a previous
     # keyword used before this "Wait For Karaf Log" keyword was closing the karaf console connection, so the
     # "Flexible SSH Login" keyword from the patch above (45596) was failing.
     # however, the consumers of this keyword were breaking after that change.    Initial theory is that a previous
     # keyword used before this "Wait For Karaf Log" keyword was closing the karaf console connection, so the
     # "Flexible SSH Login" keyword from the patch above (45596) was failing.
-    Log    Waiting for '${message}' in karaf log
-    Open Connection    ${ODL_SYSTEM_IP}    port=${KARAF_SHELL_PORT}    prompt=${KARAF_PROMPT}    timeout=${timeout}
-    Login    ${KARAF_USER}    ${KARAF_PASSWORD}    loglevel=${loglevel}
-    Write    log:tail
-    Read Until    ${message}
-    Close Connection
+    BuiltIn.Log    Waiting for '${message}' in karaf log
+    SSHLibrary.Open_Connection    ${ODL_SYSTEM_IP}    port=${KARAF_SHELL_PORT}    prompt=${KARAF_PROMPT_LOGIN}    timeout=${timeout}
+    SSHLibrary.Login    ${KARAF_USER}    ${KARAF_PASSWORD}    loglevel=${loglevel}
+    SSHLibrary.Write    log:tail
+    SSHLibrary.Read_Until    ${message}
+    SSHLibrary.Write    logout
+    SSHLibrary.Close_Connection
+
+Restart_Bundle
+    [Arguments]    ${bundle_id}
+    [Documentation]    Restarts bundle passed as argument. Note this operation is only for testing and not production environments
+    # TODO: prepare this for cluster environment and multiple controllers
+    Execute_Controller_Karaf_Command_With_Retry_On_Background    bundle:restart $(bundle:id '${bundle_id}')
+
+Restart_Karaf
+    [Documentation]    Restarts Karaf and polls log to detect when Karaf is up and running again
+    # TODO: prepare this for cluster environment and multiple controllers
+    Execute_Controller_Karaf_Command_With_Retry_On_Background    log:clear
+    Execute_Controller_Karaf_Command_With_Retry_On_Background    shutdown -r -f
+    BuiltIn.Run_Keyword_And_Return_Status    BuiltIn.Wait_Until_Keyword_Succeeds    240s    60s    Wait_For_Karaf_Log    Shiro environment initialized in
+
+Restart_Jetty
+    [Documentation]    Restarts jetty bundle (to reload certificates or key/truststore information)
+    Execute_Controller_Karaf_Command_With_Retry_On_Background    log:clear
+    Restart_Bundle    OPS4J Pax Web - Jetty
+    Wait_For_Karaf_Log    Started jetty-default