Add Rpc Provider Test Suites
[integration/test.git] / csit / libraries / ClusterManagement.robot
index 85ebb124b678e8134b1b1fae9503516eeb84d51c..b3949685799458bb703bc8789e661de319805f87 100644 (file)
@@ -23,7 +23,7 @@ Documentation     Resource housing Keywords common to several suites for cluster
 ...               - Cluster Setup
 ...               - Shard state, leader and followers
 ...               - Entity Owner, candidates and successors
-...               - Kill and Start Member
+...               - Kill, Stop and Start Member
 ...               - Isolate and Rejoin Member
 ...               - Run Commands On Member
 ...               - REST requests and checks on Members
@@ -50,6 +50,11 @@ ${SINGLETON_NETCONF_DEVICE_ID_PREFIX}    /odl-general-entity:entity[odl-general-
 ${SINGLETON_NETCONF_DEVICE_ID_SUFFIX}    ]]]]}']
 ${SINGLETON_ELECTION_ENTITY_TYPE}    org.opendaylight.mdsal.ServiceEntityType
 ${SINGLETON_CHANGE_OWNERSHIP_ENTITY_TYPE}    org.opendaylight.mdsal.AsyncServiceCloseEntityType
+${NODE_START_COMMAND}    ${KARAF_HOME}/bin/start
+${NODE_STOP_COMMAND}    ${KARAF_HOME}/bin/stop
+${NODE_KILL_COMMAND}    ps axf | grep org.apache.karaf | grep -v grep | awk '{print \"kill -9 \" $1}' | sh
+${NODE_FREEZE_COMMAND}    ps axf | grep org.apache.karaf | grep -v grep | awk '{print \"kill -STOP \" $1}' | sh
+${NODE_UNFREEZE_COMMAND}    ps axf | grep org.apache.karaf | grep -v grep | awk '{print \"kill -CONT \" $1}' | sh
 
 *** Keywords ***
 ClusterManagement_Setup
@@ -137,8 +142,17 @@ Get_Raft_State_Of_Shard_At_Member
     ${raft_state} =    Collections.Get_From_Dictionary    ${value}    RaftState
     [Return]    ${raft_state}
 
+Verify_Shard_Leader_Elected
+    [Arguments]    ${shard_name}    ${shard_type}    ${new_elected}    ${old_leader}    ${member_index_list}=${EMPTY}
+    [Documentation]    Verify new leader was elected or remained the same. Bool paramter ${new_elected} indicates if
+    ...    new leader is elected or should remained the same as ${old_leader}
+    ${leader}    ${followers}=    Get_Leader_And_Followers_For_Shard    shard_name=${shard_name}    shard_type=${shard_type}    member_index_list=${member_index_list}
+    BuiltIn.Run_Keyword_If    ${new_elected}    BuiltIn.Should_Not_Be_Equal_As_Numbers    ${old_leader}    ${leader}
+    BuiltIn.Run_Keyword_Unless    ${new_elected}    BuiltIn.Should_Be_Equal_As_numbers    ${old_leader}    ${leader}
+    BuiltIn.Return_From_Keyword    ${leader}    ${followers}
+
 Verify_Owner_And_Successors_For_Device
-    [Arguments]    ${device_name}    ${device_type}    ${member_index}    ${candidate_list}=${EMPTY}
+    [Arguments]    ${device_name}    ${device_type}    ${member_index}    ${candidate_list}=${EMPTY}    ${after_stop}=False
     [Documentation]    Returns the owner and successors for the SB device ${device_name} of type ${device_type}. Request is sent to member ${member_index}.
     ...    For Boron and beyond, candidates are not removed on node down or isolation,
     ...    so this keyword expects candidates to be all members from Boron on.
@@ -149,7 +163,8 @@ Verify_Owner_And_Successors_For_Device
     ${index_list} =    ClusterManagement__Given_Or_Internal_Index_List    given_list=${candidate_list}
     ${owner}    ${successor_list} =    Get_Owner_And_Successors_For_Device    device_name=${device_name}    device_type=${device_type}    member_index=${member_index}
     Collections.List_Should_Contain_Value    ${index_list}    ${owner}    Owner ${owner} is not in candidate list ${index_list}
-    ${expected_candidate_list_origin} =    CompareStream.Set_Variable_If_At_Least_Boron    ${ClusterManagement__member_index_list}    ${index_list}
+    # In Beryllium or after stopping an instance, the removed instance does not show in the candidate list.
+    ${expected_candidate_list_origin} =    BuiltIn.Set_Variable_If    '${ODL_STREAM}' == 'beryllium' or ${after_stop}    ${index_list}    ${ClusterManagement__member_index_list}
     # We do not want to manipulate either origin list.
     ${expected_successor_list} =    BuiltIn.Create_List    @{expected_candidate_list_origin}
     Collections.Remove_Values_From_List    ${expected_successor_list}    ${owner}
@@ -322,8 +337,7 @@ Kill_Members_From_List_Or_All
     ...    The KW will return a list of available members: \${updated index_list}=\${original_index_list}-\${member_index_list}
     ${kill_index_list} =    ClusterManagement__Given_Or_Internal_Index_List    given_list=${member_index_list}
     ${index_list} =    ClusterManagement__Given_Or_Internal_Index_List    given_list=${original_index_list}
-    ${command} =    BuiltIn.Set_Variable    ps axf | grep karaf | grep -v grep | awk '{print \"kill -9 \" $1}' | sh
-    Run_Bash_Command_On_List_Or_All    command=${command}    member_index_list=${member_index_list}
+    Run_Bash_Command_On_List_Or_All    command=${NODE_KILL_COMMAND}    member_index_list=${member_index_list}
     ${updated_index_list} =    BuiltIn.Create_List    @{index_list}
     Collections.Remove_Values_From_List    ${updated_index_list}    @{kill_index_list}
     BuiltIn.Return_From_Keyword_If    not ${confirm}    ${updated_index_list}
@@ -333,6 +347,29 @@ Kill_Members_From_List_Or_All
     \    Verify_Karaf_Is_Not_Running_On_Member    member_index=${index}
     [Return]    ${updated_index_list}
 
+Stop_Single_Member
+    [Arguments]    ${member}    ${original_index_list}=${EMPTY}    ${confirm}=True
+    [Documentation]    Convenience keyword that stops the specified member of the cluster.
+    ...    The KW will return a list of available members: \${updated index_list}=\${original_index_list}-\${member}
+    ${index_list} =    ClusterManagement__Build_List    ${member}
+    ${updated_index_list} =    Stop_Members_From_List_Or_All    ${index_list}    ${original_index_list}    ${confirm}
+    [Return]    ${updated_index_list}
+
+Stop_Members_From_List_Or_All
+    [Arguments]    ${member_index_list}=${EMPTY}    ${original_index_list}=${EMPTY}    ${confirm}=True    ${timeout}=120s
+    [Documentation]    If the list is empty, stops all ODL instances. Otherwise stop members based on \${stop_index_list}
+    ...    If \${confirm} is True, verify stopped instances are not there anymore.
+    ...    The KW will return a list of available members: \${updated index_list}=\${original_index_list}-\${member_index_list}
+    ${stop_index_list} =    ClusterManagement__Given_Or_Internal_Index_List    given_list=${member_index_list}
+    ${index_list} =    ClusterManagement__Given_Or_Internal_Index_List    given_list=${original_index_list}
+    Run_Bash_Command_On_List_Or_All    command=${NODE_STOP_COMMAND}    member_index_list=${member_index_list}
+    ${updated_index_list} =    BuiltIn.Create_List    @{index_list}
+    Collections.Remove_Values_From_List    ${updated_index_list}    @{stop_index_list}
+    BuiltIn.Return_From_Keyword_If    not ${confirm}    ${updated_index_list}
+    : FOR    ${index}    IN    @{stop_index_list}
+    \    BuiltIn.Wait Until Keyword Succeeds    ${timeout}    2s    Verify_Karaf_Is_Not_Running_On_Member    member_index=${index}
+    [Return]    ${updated_index_list}
+
 Start_Single_Member
     [Arguments]    ${member}    ${wait_for_sync}=True    ${timeout}=300s
     [Documentation]    Convenience keyword that starts the specified member of the cluster.
@@ -340,17 +377,37 @@ Start_Single_Member
     Start_Members_From_List_Or_All    ${index_list}    ${wait_for_sync}    ${timeout}
 
 Start_Members_From_List_Or_All
-    [Arguments]    ${member_index_list}=${EMPTY}    ${wait_for_sync}=True    ${timeout}=300s    ${karaf_home}=${KARAF_HOME}    ${export_java_home}=${JAVA_HOME}
+    [Arguments]    ${member_index_list}=${EMPTY}    ${wait_for_sync}=True    ${timeout}=300s    ${karaf_home}=${EMPTY}    ${export_java_home}=${EMPTY}
     [Documentation]    If the list is empty, start all cluster members. Otherwise, start members based on present indices.
     ...    If ${wait_for_sync}, wait for cluster sync on listed members.
     ...    Optionally karaf_home can be overriden. Optionally specific JAVA_HOME is used for starting.
-    ${base_command} =    BuiltIn.Set_Variable    ${karaf_home}/bin/start
+    ${base_command} =    BuiltIn.Set_Variable_If    "${karaf_home}"    ${karaf_home}/bin/start    ${NODE_START_COMMAND}
     ${command} =    BuiltIn.Set_Variable_If    "${export_java_home}"    export JAVA_HOME="${export_java_home}"; ${base_command}    ${base_command}
     Run_Bash_Command_On_List_Or_All    command=${command}    member_index_list=${member_index_list}
     BuiltIn.Return_From_Keyword_If    not ${wait_for_sync}
     BuiltIn.Wait_Until_Keyword_Succeeds    ${timeout}    10s    Check_Cluster_Is_In_Sync    member_index_list=${member_index_list}
     # TODO: Do we also want to check Shard Leaders here?
 
+Freeze_Single_Member
+    [Arguments]    ${member}
+    [Documentation]    Convenience keyword that stops the specified member of the cluster by freezing the jvm.
+    ${index_list} =    ClusterManagement__Build_List    ${member}
+    Freeze_Or_Unfreeze_Members_From_List_Or_All    ${NODE_FREEZE_COMMAND}    ${index_list}
+
+Unfreeze_Single_Member
+    [Arguments]    ${member}    ${wait_for_sync}=True    ${timeout}=60s
+    [Documentation]    Convenience keyword that "continues" the specified member of the cluster by unfreezing the jvm.
+    ${index_list} =    ClusterManagement__Build_List    ${member}
+    Freeze_Or_Unfreeze_Members_From_List_Or_All    ${NODE_UNFREEZE_COMMAND}    ${index_list}
+    BuiltIn.Wait_Until_Keyword_Succeeds    ${timeout}    10s    Check_Cluster_Is_In_Sync
+
+Freeze_Or_Unfreeze_Members_From_List_Or_All
+    [Arguments]    ${command}    ${member_index_list}=${EMPTY}
+    [Documentation]    If the list is empty, stops/runs all ODL instances. Otherwise stop/run members based on \${stop_index_list}
+    ...    For command parameter only ${NODE_FREEZE_COMMAND} and ${NODE_UNFREEZE_COMMAND} should be used
+    ${freeze_index_list} =    ClusterManagement__Given_Or_Internal_Index_List    given_list=${member_index_list}
+    Run_Bash_Command_On_List_Or_All    command=${command}    member_index_list=${member_index_list}
+
 Clean_Journals_And_Snapshots_On_List_Or_All
     [Arguments]    ${member_index_list}=${EMPTY}    ${karaf_home}=${KARAF_HOME}
     [Documentation]    Delete journal and snapshots directories on every node listed (or all).
@@ -374,7 +431,7 @@ Verify_Single_Karaf_Is_Running_On_Member
 Count_Running_Karafs_On_Member
     [Arguments]    ${member_index}
     [Documentation]    Remotely execute grep for karaf process, return count as string.
-    ${command} =    BuiltIn.Set_Variable    ps axf | grep karaf | grep -v grep | wc -l
+    ${command} =    BuiltIn.Set_Variable    ps axf | grep org.apache.karaf | grep -v grep | wc -l
     ${count} =    Run_Bash_Command_On_Member    command=${command}    member_index=${member_index}
     [Return]    ${count}
 
@@ -492,6 +549,16 @@ Clean_Directories_On_List_Or_All
     ${path_list} =    Builtin.Set Variable If    "${directory_list}" == "${EMPTY}"    ${ODL_DEFAULT_DATA_PATHS}    ${directory_list}
     Safe_With_Ssh_To_List_Or_All_Run_Keyword    ${member_index_list}    ClusterManagement__Clean_Directories    ${path_list}    ${karaf_home}
 
+Store_Karaf_Log_On_List_Or_All
+    [Arguments]    ${member_index_list}=${EMPTY}    ${dst_dir}=/tmp    ${karaf_home}=${KARAF_HOME}
+    [Documentation]    Saves karaf.log to the ${dst_dir} for members in given list or all. Return None.
+    Safe_With_Ssh_To_List_Or_All_Run_Keyword    ${member_index_list}    SSHKeywords.Execute_Command_Should_Pass    cp ${karaf_home}/data/log/karaf.log ${dst_dir}
+
+Restore_Karaf_Log_On_List_Or_All
+    [Arguments]    ${member_index_list}=${EMPTY}    ${src_dir}=/tmp    ${karaf_home}=${KARAF_HOME}
+    [Documentation]    Places stored karaf.log to the ${karaf_home}/data/log for members in given list or all. Return None.
+    Safe_With_Ssh_To_List_Or_All_Run_Keyword    ${member_index_list}    SSHKeywords.Execute_Command_Should_Pass    cp ${src_dir}/karaf.log ${karaf_home}/data/log/
+
 ClusterManagement__Clean_Directories
     [Arguments]    ${relative_path_list}    ${karaf_home}
     [Documentation]    For each relative path, remove files with respect to ${karaf_home}. Return None.
@@ -603,10 +670,15 @@ ClusterManagement__Parse_Sync_Status
     ${sync_status} =    Collections.Get_From_Dictionary    dictionary=${value_object}    key=SyncStatus
     [Return]    ${sync_status}
 
+List_All_Indices
+    [Documentation]    Create a new list of all indices.
+    ${return_list_copy} =    ClusterManagement__Given_Or_Internal_Index_List
+    BuiltIn.Return_From_Keyword    ${return_list_copy}
+
 List_Indices_Minus_Member
     [Arguments]    ${member_index}    ${member_index_list}=${EMPTY}
     [Documentation]    Create a new list which contains indices from ${member_index_list} (or all) without ${member_index}.
-    ${index_list} =    ClusterManagement__Given_Or_Empty_List    ${member_index_list}
+    ${index_list} =    ClusterManagement__Given_Or_Internal_Index_List    ${member_index_list}
     Collections.Remove Values From List    ${index_list}    ${member_index}
     [Return]    ${index_list}
 
@@ -653,3 +725,15 @@ ClusterManagement__Include_Member_Index
     ${session_alias} =    Resolve_Http_Session_For_Member    member_index=${index}
     RequestsLibrary.Create_Session    ${session_alias}    http://${member_ip}:${RESTCONFPORT}    auth=${AUTH}    max_retries=0
     Collections.Append_To_List    ${session_list}    ${session_alias}
+
+Sync_Status_Should_Be_False
+    [Arguments]    ${controller_index}
+    [Documentation]    Verify that cluster node is not in sync with others
+    ${status}    Get_Sync_Status_Of_Member    ${controller_index}
+    BuiltIn.Should_Not_Be_True    ${status}
+
+Sync_Status_Should_Be_True
+    [Arguments]    ${controller_index}
+    [Documentation]    Verify that cluster node is in sync with others
+    ${status}    Get_Sync_Status_Of_Member    ${controller_index}
+    BuiltIn.Should_Be_True    ${status}