Upgrade RF syntax for v3.2 compatibility
[integration/test.git] / csit / libraries / Coe.robot
1 *** Settings ***
2 Library           BuiltIn
3 Library           SSHLibrary
4 Library           String
5 Resource          DataModels.robot
6 Resource          Genius.robot
7 Resource          OVSDB.robot
8 Resource          SSHKeywords.robot
9 Resource          Utils.robot
10 Resource          ../variables/netvirt/Variables.robot
11 Resource          ../variables/Variables.robot
12 Resource          VpnOperations.robot
13 Variables         ../variables/coe/Modules.py
14 Variables         ../variables/netvirt/Modules.py
15 Resource          ToolsSystem.robot
16
17 *** Variables ***
18 ${BUSY_BOX}       ${CURDIR}/../variables/coe/busy-box.yaml
19 ${CNI_BINARY_FILE}    /opt/cni/bin/odlovs-cni
20 ${CONFIG_FILE}    /etc/cni/net.d/odlovs-cni.conf
21 ${CONFIG_FILE_TEMPLATE}    ${CURDIR}/../variables/coe/odlovs-cni.conf.j2
22 ${HOST_INVENTORY}    ${CURDIR}/../variables/coe/hosts.yaml
23 ${K8s_MASTER_IP}    ${TOOLS_SYSTEM_1_IP}
24 ${HOSTS_FILE_TEMPLATE}    ${CURDIR}/../variables/coe/minions_template.yaml
25 ${NODE_READY_STATUS}    \\sReady    # The check using this variable should not mess up with NotReady
26 ${PLAYBOOK_FILE}    ${CURDIR}/../variables/coe/coe_play.yaml
27 ${POD_RUNNING_STATUS}    \\sRunning
28 ${VARIABLES_PATH}    ${CURDIR}/../variables/coe
29 ${WATCHER_COE}    ${CURDIR}/../variables/coe/coe.yaml
30 @{COE_DIAG_SERVICES}    OPENFLOW    IFM    ITM    DATASTORE    ELAN    OVSDB
31
32 *** Keywords ***
33 Coe Suite Setup
34     [Documentation]    COE project requires start suite to be executed only for the first test suite.This keyword find the current suite,compares it with the stored first suite value and executes Coe.Start suite only if the cuurent suite is equal to the first suite.
35     ToolsSystem.Get Tools System Nodes Data
36     Coe.Set Connection ids and Bridge
37     Coe.Derive Coe Data Models
38     ${current suite}    ${suite names updated}    Extract current suite name
39     ${first_suite} =    Set Variable    ${suite names updated[0]}
40     ${status} =    BuiltIn.Evaluate    '${first_suite}' == '${current suite}'
41     Run Keyword If    '${status}' == 'True'    Coe.Start Suite
42
43 Start Suite
44     [Documentation]    Suite setup keyword.
45     Coe.Configuration Playbook
46     Coe.Verify Config Files
47     Coe.Verify Watcher Is Running
48     BuiltIn.Wait Until Keyword Succeeds    40s    2s    Coe.Check Node Status Is Ready
49     Coe.Label Nodes
50     BuiltIn.Wait Until Keyword Succeeds    60    2    ClusterManagement.Check Status Of Services Is OPERATIONAL    @{COE_DIAG_SERVICES}
51     BuiltIn.Wait Until Keyword Succeeds    85    2    Genius.Verify Tunnel Status As Up
52
53 Set Connection ids and Bridge
54     [Documentation]    Sets the connection ids for all the nodes and get the bridge from configuration file .
55     FOR    ${conn_id}    IN    @{TOOLS_SYSTEM_ALL_CONN_IDS}
56         SSHLibrary.Switch Connection    ${conn_id}
57         SSHKeywords.Flexible_SSH_Login    ${DEFAULT_USER}    ${DEFAULT_PASSWORD}
58     END
59     ${file} =    OperatingSystem.Get File    ${CONFIG_FILE_TEMPLATE}
60     ${ovs bridge output}    ${bridge} =    BuiltIn.Should Match Regexp    ${file}    "ovsBridge": "(\\w.*)"
61     BuiltIn.Set Suite Variable    ${bridge}
62
63 Configuration Playbook
64     [Documentation]    Ansible playbook which does all basic configuration for kubernetes nodes.
65     ${playbook minions}    ${playbook hosts}    ${host file}    Modifying templates in playbook
66     ${playbook} =    OperatingSystem.Get File    ${PLAYBOOK_FILE}
67     ${playbook} =    String.Replace String    ${playbook}    coe-hosts    ${playbook hosts}
68     ${playbook} =    String.Replace String    ${playbook}    coe-minions    ${playbook minions}
69     OperatingSystem.Create File    ${PLAYBOOK_FILE}    ${playbook}
70     OperatingSystem.Create File    ${USER_HOME}/hosts.yaml    ${host file}
71     ${watcher} =    OperatingSystem.Get File    ${WATCHER_COE}
72     ${watcher} =    String.Replace String    ${watcher}    odlip    ${ODL_SYSTEM_IP}
73     ${watcher} =    String.Replace String    ${watcher}    port    ${RESTCONFPORT}
74     OperatingSystem.Create File    ${WATCHER_COE}    ${watcher}
75     SSHKeywords.Copy_File_To_Remote_System    ${K8s_MASTER_IP}    ${WATCHER_COE}    ${USER_HOME}
76     OperatingSystem.Copy File    ${PLAYBOOK_FILE}    ${USER_HOME}
77     ${branch_ref_spec} =    BuiltIn.Catenate    SEPARATOR=    refs/heads/    ${GERRIT_BRANCH}
78     ${gerrit_ref_spec} =    BuiltIn.Set Variable If    '${GERRIT_PROJECT}' != 'coe'    ${branch_ref_spec}    ${GERRIT_REFSPEC}
79     Run Coe Playbook    ${gerrit_ref_spec}
80
81 Run Coe Playbook
82     [Arguments]    ${gerrit_ref_spec}
83     ${play_output} =    OperatingSystem.Run    ansible-playbook -v ${USER_HOME}/coe_play.yaml -i ${USER_HOME}/hosts.yaml --extra-vars '{"gerrit_branch":"FETCH_HEAD","gerrit_refspec":"${gerrit_ref_spec}"}'
84     BuiltIn.Log    ${play_output}
85
86 Modifying templates in playbook
87     ${inventory} =    OperatingSystem.Get File    ${HOST_INVENTORY}
88     ${template} =    OperatingSystem.Get File    ${HOSTS_FILE_TEMPLATE}
89     ${template} =    String.Replace String    ${template}    minion_ip    ${TOOLS_SYSTEM_ALL_IPS[0]}
90     @{minions}    Create List    coe-minion
91     ${hosts}    Set Variable    coe-master:
92     FOR    ${i}    IN RANGE    1    ${NUM_TOOLS_SYSTEM}
93         Append To List    ${minions}    coe-minion${i}
94         ${hosts} =    Catenate    ${hosts}    coe-minion${i}:
95     END
96     ${hosts} =    Replace String Using Regexp    ${hosts}    :$    ${EMPTY}
97     ${hosts} =    Remove Space on String    ${hosts}
98     ${minion hosts} =    Replace String Using Regexp    ${hosts}    ^[\\w-]+:    ${EMPTY}
99     FOR    ${i}    IN RANGE    1    ${NUM_TOOLS_SYSTEM}
100         ${j} =    Evaluate    ${i}+1
101         ${template} =    String.Replace String    ${template}    ${minions[${i}-1]}    ${minions[${i}]}
102         ${template} =    String.Replace String    ${template}    ${TOOLS_SYSTEM_ALL_IPS[${i}-1]}    ${TOOLS_SYSTEM_ALL_IPS[${i}]}
103         ${template} =    String.Replace String    ${template}    192.168.50.1${i}    192.168.50.1${j}
104         ${template} =    String.Replace String    ${template}    10.11.${i}.0/24    10.11.${j}.0/24
105         ${template} =    String.Replace String    ${template}    10.11.${i}.1    10.11.${j}.1
106         Append To File    ${HOST_INVENTORY}    ${template}
107     END
108     ${host file} =    OperatingSystem.Get File    ${HOST_INVENTORY}
109     ${host file} =    String.Replace String    ${host file}    master_ip    ${TOOLS_SYSTEM_ALL_IPS[0]}
110     ${host file} =    String.Replace String    ${host file}    odl_ip    ${ODL_SYSTEM_IP}
111     ${host file} =    String.Replace String    ${host file}    mport    ${OVSDBPORT}
112     ${host file} =    String.Replace String    ${host file}    cport    ${ODL_OF_PORT_6653}
113     ${host file} =    String.Replace String    ${host file}    filepath    ${CONFIG_FILE_TEMPLATE}
114     ${host file} =    String.Replace String    ${host file}    yamlpath    ${USER_HOME}/coe.yaml
115     log    ${host file}
116     [Return]    ${minion hosts}    ${hosts}    ${host file}
117
118 Verify Config Files
119     [Documentation]    Checks if the configuration files are present in all nodes
120     FOR    ${nodes}    IN    @{TOOLS_SYSTEM_ALL_IPS}
121         Utils.Verify File Exists On Remote System    ${nodes}    ${CONFIG_FILE}
122     END
123     FOR    ${nodes}    IN    @{TOOLS_SYSTEM_ALL_IPS}
124         Utils.Verify File Exists On Remote System    ${nodes}    ${CNI_BINARY_FILE}
125     END
126
127 Verify Watcher Is Running
128     [Documentation]    Checks if watcher is running in the background
129     ${watcher status} =    Utils.Run Command On Remote System    ${K8s_MASTER_IP}    ps -ef | grep watcher
130     BuiltIn.Should Match Regexp    ${watcher status}    .* watcher odl
131
132 Check Node Status Is Ready
133     [Documentation]    Checks the status of nodes.This keyword is repeated until the status of all nodes is Ready
134     ${nodes} =    Utils.Run Command On Remote System And Log    ${K8s_MASTER_IP}    kubectl get nodes    ${DEFAULT_USER}    ${DEFAULT_PASSWORD}    ${DEFAULT_LINUX_PROMPT_STRICT}
135     ${node_status} =    String.Get Lines Matching Regexp    ${nodes}    ${NODE_READY_STATUS}    partial_match=True
136     ${lines_containing_ready} =    String.Get Line Count    ${node_status}
137     BuiltIn.Should Be Equal As Strings    ${lines_containing_ready}    ${NUM_TOOLS_SYSTEM}
138
139 Label Nodes
140     [Documentation]    Create labels for minions so that random allocation of pods to minions is avoided
141     ${i} =    BuiltIn.Set Variable    1
142     ${get nodes} =    Utils.Run Command On Remote System And Log    ${K8s_MASTER_IP}    kubectl get nodes
143     @{get nodes} =    String.Split To Lines    ${get nodes}    2
144     FOR    ${status}    IN    @{get nodes}
145         ${minion} =    BuiltIn.Should Match Regexp    ${status}    ^\\w+-.*-\\d+
146         Utils.Run Command On Remote System And Log    ${K8s_MASTER_IP}    kubectl label nodes ${minion} disktype=ss${i}
147         ${i} =    BuiltIn.Evaluate    ${i}+1
148     END
149     Utils.Run Command On Remote System And Log    ${K8s_MASTER_IP}    kubectl get nodes --show-labels
150
151 Derive Coe Data Models
152     [Documentation]    Data models is created by integrating netvirt and coe data models which is given as input to get the model dumps
153     FOR    ${models}    IN    @{netvirt_data_models}
154         Collections.Append To List    ${coe_data_models}    ${models}
155     END
156
157 Check Pod Status Is Running
158     [Documentation]    Checks the status of pods.This keyword is repeated until the status of all pods is Running
159     ${pods} =    Utils.Run Command On Remote System And Log    ${K8s_MASTER_IP}    kubectl get pods -o wide    ${DEFAULT_USER}    ${DEFAULT_PASSWORD}    ${DEFAULT_LINUX_PROMPT_STRICT}
160     @{cluster} =    String.Split To Lines    ${pods}    1
161     FOR    ${pod}    IN    @{cluster}
162         BuiltIn.Should Match Regexp    ${pod}    ${POD_RUNNING_STATUS}
163     END
164
165 Tear Down
166     [Documentation]    Test teardown to get dumpflows,ovsconfig,model dump,node status,pod status and to dump config files \ and delete pods.
167     FOR    ${conn_id}    IN    @{TOOLS_SYSTEM_ALL_CONN_IDS}
168         OVSDB.Get DumpFlows And Ovsconfig    ${conn_id}    ${bridge}
169     END
170     BuiltIn.Run Keyword And Ignore Error    DataModels.Get Model Dump    ${ODL_SYSTEM_IP}    ${coe_data_models}
171     Coe.DumpConfig File
172     Utils.Run Command On Remote System And Log    ${K8s_MASTER_IP}    kubectl get nodes    ${DEFAULT_USER}    ${DEFAULT_PASSWORD}    ${DEFAULT_LINUX_PROMPT_STRICT}
173     Utils.Run Command On Remote System And Log    ${K8s_MASTER_IP}    kubectl get pods -o wide    ${DEFAULT_USER}    ${DEFAULT_PASSWORD}    ${DEFAULT_LINUX_PROMPT_STRICT}
174     Coe.Delete Pods
175
176 Delete Pods
177     [Documentation]    Waits till the keyword delete status succeeds implying that all pods created have been deleted
178     ${get pods} =    Utils.Run Command On Remote System    ${K8s_MASTER_IP}    kubectl get pods -o wide
179     @{get pods} =    String.Split To Lines    ${get pods}    1
180     FOR    ${status}    IN    @{get pods}
181         ${pod_name} =    BuiltIn.Should Match Regexp    ${status}    ^\\w+-\\w+
182         Utils.Run Command On Remote System    ${K8s_MASTER_IP}    kubectl delete pods ${pod_name}
183     END
184     BuiltIn.Wait Until Keyword Succeeds    60s    3s    Coe.Check If Pods Are Terminated
185     Coe.Check For Stale veth Ports
186
187 Check If Pods Are Terminated
188     [Documentation]    Checks if the pods created have been terminated.The keyword is repeated until the pods are deleted
189     ${status} =    Utils.Run Command On Remote System    ${K8s_MASTER_IP}    kubectl get pods -o wide    ${DEFAULT_USER}    ${DEFAULT_PASSWORD}    ${DEFAULT_LINUX_PROMPT_STRICT}
190     ...    ${DEFAULT_TIMEOUT}    return_stdout=False    return_stderr=True
191     BuiltIn.Should Contain    ${status}    No resources
192
193 Dump Config File
194     [Documentation]    Logs the configuration files present in all nodes
195     FOR    ${nodes}    IN    @{TOOLS_SYSTEM_ALL_IPS}
196         Utils.Run Command On Remote System And Log    ${nodes}    cat ${CONFIG_FILE}
197     END
198
199 Stop Suite
200     [Documentation]    Suite teardown keyword
201     Coe.Collect Watcher Log
202     Coe.Collect Journalctl Log
203     Coe.Stop_Watcher
204     Coe.Kube_reset
205     SSHLibrary.Close All Connections
206
207 Collect Watcher Log
208     [Documentation]    Watcher running in background logs into watcher.out which is copied to ${JENKINS_WORKSPACE}/archives/watcher.log
209     SSHLibrary.Switch Connection    ${TOOLS_SYSTEM_ALL_CONN_IDS[0]}
210     SSHLibrary.Get File    /tmp/watcher.out    ${JENKINS_WORKSPACE}/archives/watcher.log
211
212 Collect Journalctl Log
213     [Documentation]    Logs of the command journalctl -u kubelet is copied to ${JENKINS_WORKSPACE}/archives/journal.log
214     Utils.Run Command On Remote System And Log    ${K8s_MASTER_IP}    sudo journalctl -u kubelet > ${USER_HOME}/journal.txt
215     SSHLibrary.Switch Connection    ${TOOLS_SYSTEM_ALL_CONN_IDS[0]}
216     SSHLibrary.Get File    ${USER_HOME}/journal.txt    ${JENKINS_WORKSPACE}/archives/journalctl.log
217
218 Stop Watcher
219     [Documentation]    Kill the watcher running at the background after completion of tests cases
220     ${watcher status} =    Utils.Run Command On Remote System    ${K8s_MASTER_IP}    ps -ef | grep watcher
221     ${watcher}    ${pid} =    BuiltIn.Should Match Regexp    ${watcher status}    \\w+\\s+(\\d+).*watcher odl
222     Utils.Run Command On Remote System    ${K8s_MASTER_IP}    kill -9 ${pid}
223
224 Kube reset
225     [Documentation]    Reset K8s to clear up all stale entries
226     FOR    ${nodes}    IN    @{TOOLS_SYSTEM_ALL_IPS}
227         ${kube} =    Utils.Run Command On Remote System And Log    ${nodes}    sudo kubeadm reset
228         BuiltIn.Should Contain    ${kube}    Stopping the kubelet service.
229     END
230
231 Create Pods
232     [Arguments]    ${label}    ${yaml}    ${name}
233     [Documentation]    Creates pods using the labels of the nodes and busy box names passed as arguments.
234     ${busybox} =    OperatingSystem.Get File    ${BUSY_BOX}
235     ${busybox} =    String.Replace String    ${busybox}    string    ${label}
236     ${busybox} =    String.Replace String    ${busybox}    busyboxname    ${name}
237     OperatingSystem.Create File    ${VARIABLES_PATH}/${yaml}    ${busybox}
238     SSHKeywords.Move_file_To_Remote_System    ${K8s_MASTER_IP}    ${VARIABLES_PATH}/${yaml}    ${USER_HOME}
239     Utils.Run Command On Remote System And Log    ${K8s_MASTER_IP}    kubectl create -f ${yaml}
240
241 Collect Pod Names and Ping
242     [Documentation]    This keyword collects the pod names and checks connectivity between each and every pod with respect to one another.
243     SSHLibrary.Switch Connection    ${TOOLS_SYSTEM_ALL_CONN_IDS[0]}
244     ${get pods} =    Write Commands Until Expected Prompt    kubectl get pods -o wide    ${DEFAULT_LINUX_PROMPT_STRICT}
245     @{pod ips} =    String.Get Regexp Matches    ${get pods}    \\d+\\.\\d+\\.\\d+\\.\\d+
246     @{pod names} =    String.Get Regexp Matches    ${get pods}    ss\\w+-\\w+
247     FOR    ${pod_name}    IN    @{pod names}
248         ${logs} =    Log Statements    ${pod ips}    ${pod names}    ${pod_name}
249         Ping Pods    ${pod_name}    ${pod ips}    ${logs}
250     END
251
252 Log Statements
253     [Arguments]    ${pod ips}    ${pod names}    ${pod_name}
254     @{log statement} =    Create List
255     ${i} =    Set Variable    0
256     FOR    ${pod_ip}    IN    @{pod ips}
257         ${ping statement}    Set Variable    Ping from ${pod_name} to ${pod names[${i}]} (${pod ip})
258         Append To List    ${log statement}    ${ping statement}
259         ${i} =    Evaluate    ${i}+1
260     END
261     [Return]    @{log statement}
262
263 Ping Pods
264     [Arguments]    ${pod_name}    ${pod ips}    ${logs}
265     ${i} =    Set Variable    0
266     FOR    ${ping info}    IN    @{logs}
267         ${ping} =    Write Commands Until Expected Prompt    kubectl exec -it ${pod_name} -- ping -c 3 ${pod ips[${i}]}    ${DEFAULT_LINUX_PROMPT_STRICT}
268         BuiltIn.log    ${ping}
269         BuiltIn.Should Contain    ${ping}    64 bytes
270         ${i}    Evaluate    ${i}+1
271     END
272
273 Coe Suite Teardown
274     [Documentation]    COE project requires stop suite to be executed only for the last test suite.This keyword find the current suite,compares it with the stored last suite value and executes Coe.Stop suite only if the cuurent suite is equal to the last suite.
275     ${current suite}    ${suite names updated}    Extract current suite name
276     ${last_suite} =    Set Variable    ${suite names updated[-1]}
277     ${status} =    BuiltIn.Evaluate    '${last_suite}' == '${current suite}'
278     Run Keyword If    '${status}' == 'True'    Coe.Stop Suite
279
280 Extract current suite name
281     [Documentation]    This keyword returns the name of current test suite.Appropriate replacement in text is done to make test suite names in SUITES and SUITE_NAME similar.
282     BuiltIn.Log    SUITE_NAME: ${SUITE_NAME}
283     BuiltIn.Log    SUITES: ${SUITES}
284     @{suite_names}    Get Regexp Matches    ${SUITES}    coe\\/(\\w+).robot    1
285     @{suite_names_updated}    Create List
286     FOR    ${suite}    IN    @{suite_names}
287         ${suite}    Replace String    ${suite}    _    ${SPACE}
288         Append To List    ${suite_names_updated}    ${suite}
289     END
290     ${num_suites} =    BuiltIn.Get Length    ${suite_names_updated}
291     ${suite line}    ${current_suite} =    BuiltIn.Run Keyword If    ${num_suites} > ${1}    Should Match Regexp    ${SUITE_NAME}    .txt.(\\w.*)
292     ...    ELSE    BuiltIn.Set Variable    @{suite_names_updated}[0]    @{suite_names_updated}[0]
293     [Return]    ${current_suite}    ${suite_names_updated}
294
295 Check For Stale veth Ports
296     [Documentation]    Check on switches(except master) where pods were created and deleted to ensure there are no stale veth ports left behind.
297     FOR    ${minion_index}    IN RANGE    2    ${NUM_TOOLS_SYSTEM}+1
298         ${switch output} =    Utils.Run Command On Remote System And Log    ${TOOLS_SYSTEM_${minion_index}_IP}    sudo ovs-vsctl show
299         BuiltIn.Should Not Contain    ${switch output}    veth
300     END