Support only Oxygen+ distributions
[integration/test.git] / csit / libraries / ClusterOpenFlow.robot
1 *** Settings ***
2 Documentation       Cluster OpenFlow library. So far this library is only to be used by OpenFlow cluster test as it is very specific for this test.
3
4 Library             Collections
5 Library             RequestsLibrary
6 Library             ${CURDIR}/ScaleClient.py
7 Resource            ClusterManagement.robot
8 Resource            CompareStream.robot
9 Resource            MininetKeywords.robot
10 Resource            Utils.robot
11 Resource            ../variables/openflowplugin/Variables.robot
12 Variables           ../variables/Variables.py
13
14
15 *** Variables ***
16 @{SHARD_OPER_LIST}          inventory    topology    default    entity-ownership
17 @{SHARD_CONF_LIST}          inventory    topology    default
18 ${config_table_0}           ${RFC8040_NODES_API}/node=openflow%3A1/flow-node-inventory:table=0
19 ${operational_table_0}
20 ...                         ${RFC8040_NODES_API}/node=openflow%3A1/flow-node-inventory:table=0?${RFC8040_OPERATIONAL_CONTENT}
21 ${operational_port_1}
22 ...                         ${RFC8040_NODES_API}/node=openflow%3A1/node-connector=openflow%3A1%3A1?${RFC8040_OPERATIONAL_CONTENT}
23
24
25 *** Keywords ***
26 Get InventoryConfig Shard Status
27     [Documentation]    Check Status for Inventory Config shard in OpenFlow application.
28     [Arguments]    ${controller_index_list}=${EMPTY}
29     ${inv_conf_leader}    ${inv_conf_followers_list}=    Wait Until Keyword Succeeds
30     ...    10s
31     ...    1s
32     ...    ClusterManagement.Get_Leader_And_Followers_For_Shard
33     ...    shard_name=inventory
34     ...    shard_type=config
35     ...    member_index_list=${controller_index_list}
36     Log    config inventory Leader is ${inv_conf_leader} and followers are ${inv_conf_followers_list}
37     RETURN    ${inv_conf_leader}    ${inv_conf_followers_list}
38
39 Check OpenFlow Shards Status
40     [Documentation]    Check Status for all shards in OpenFlow application.
41     [Arguments]    ${controller_index_list}=${EMPTY}
42     CompareStream.Run_Keyword_If_At_Least_Phosphorus
43     ...    Collections.Remove Values From List
44     ...    ${SHARD_OPER_LIST}
45     ...    entity-ownership
46     Log    ${SHARD_OPER_LIST}
47     ClusterManagement.Verify_Leader_Exists_For_Each_Shard
48     ...    shard_name_list=${SHARD_OPER_LIST}
49     ...    shard_type=operational
50     ...    member_index_list=${controller_index_list}
51     ClusterManagement.Verify_Leader_Exists_For_Each_Shard
52     ...    shard_name_list=${SHARD_CONF_LIST}
53     ...    shard_type=config
54     ...    member_index_list=${controller_index_list}
55
56 Check OpenFlow Shards Status After Cluster Event
57     [Documentation]    Check Shards Status after some cluster event.
58     [Arguments]    ${controller_index_list}=${EMPTY}
59     Wait Until Keyword Succeeds
60     ...    90s
61     ...    1s
62     ...    ClusterOpenFlow.Check OpenFlow Shards Status
63     ...    ${controller_index_list}
64
65 Get OpenFlow Entity Owner Status For One Device
66     [Documentation]    Check Entity Owner Status and identify owner and successors for the device ${device}. Request is sent to controller ${controller_index}.
67     [Arguments]    ${device}    ${controller_index}    ${controller_index_list}=${EMPTY}    ${after_stop}=False
68     ${owner}    ${successor_list}=    Wait Until Keyword Succeeds
69     ...    30s
70     ...    1s
71     ...    ClusterManagement.Verify_Owner_And_Successors_For_Device
72     ...    device_name=${device}
73     ...    device_type=openflow
74     ...    member_index=${controller_index}
75     ...    candidate_list=${controller_index_list}
76     ...    after_stop=${after_stop}
77     RETURN    ${owner}    ${successor_list}
78
79 Check OpenFlow Device Owner
80     [Documentation]    Check owner and candidates for the device ${device}. Request is sent to controller ${controller_index}.
81     [Arguments]    ${device}    ${controller_index}    ${expected_owner}    ${expected_candidate_list}=${EMPTY}
82     ${owner}    ${successor_list}=    ClusterManagement.Verify_Owner_And_Successors_For_Device
83     ...    device_name=${device}
84     ...    device_type=openflow
85     ...    member_index=${controller_index}
86     ...    candidate_list=${expected_candidate_list}
87     Should Be Equal    ${owner}    ${expected_owner}
88
89 Check OpenFlow Network Operational Information For Sample Topology
90     [Documentation]    Check devices in tree,2 are in operational inventory and topology in all instances in ${controller_index_list}.
91     ...    Inventory should show 1x node_id per device 1x node_id per connector. Topology should show 2x node_id per device + 3x node_id per connector
92     ...    + 5x node_id per link termination. TODO: A Keyword that can calculate this based on mininet topology.
93     [Arguments]    ${controller_index_list}=${EMPTY}
94     ${dictionary}=    Create Dictionary    openflow:1=4    openflow:2=5    openflow:3=5
95     Wait Until Keyword Succeeds
96     ...    5s
97     ...    1s
98     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
99     ...    uri=${RFC8040_OPERATIONAL_NODES_API}
100     ...    dictionary=${dictionary}
101     ...    member_index_list=${controller_index_list}
102     ${dictionary}=    Create Dictionary    openflow:1=21    openflow:2=19    openflow:3=19
103     Wait Until Keyword Succeeds
104     ...    5s
105     ...    1s
106     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
107     ...    uri=${RFC8040_OPERATIONAL_TOPO_API}
108     ...    dictionary=${dictionary}
109     ...    member_index_list=${controller_index_list}
110
111 Check No OpenFlow Network Operational Information
112     [Documentation]    Check device is not in operational inventory or topology in all cluster instances in ${controller_index_list}.
113     [Arguments]    ${controller_index_list}=${EMPTY}
114     ${dictionary}=    Create Dictionary    openflow=0
115     CompareStream.Run_Keyword_If_At_Least_Neon
116     ...    Wait Until Keyword Succeeds
117     ...    5s
118     ...    1s
119     ...    ClusterManagement.Check_No_Content_Member_List_Or_All
120     ...    uri=${RFC8040_OPERATIONAL_NODES_API}
121     ...    member_index_list=${controller_index_list}
122     CompareStream.Run_Keyword_If_At_Most_Fluorine
123     ...    Wait Until Keyword Succeeds
124     ...    5s
125     ...    1s
126     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
127     ...    uri=${RFC8040_OPERATIONAL_NODES_API}
128     ...    dictionary=${dictionary}
129     ...    member_index_list=${controller_index_list}
130     ${dictionary}=    Create Dictionary    openflow=0
131     Wait Until Keyword Succeeds
132     ...    20s
133     ...    2s
134     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
135     ...    uri=${RFC8040_OPERATIONAL_TOPO_API}
136     ...    dictionary=${dictionary}
137     ...    member_index_list=${controller_index_list}
138
139 Add Sample Flow And Verify
140     [Documentation]    Add sample flow in ${controller_index} and verify it gets applied in all instances in ${controller_index_list}.
141     [Arguments]    ${controller_index}    ${controller_index_list}=${EMPTY}
142     ${body}=    OperatingSystem.Get File    ${CURDIR}/../variables/openflowplugin/sample_flow_1.json
143     # There are slight differences on the way He and Li plugin display table information. He plugin has an additional Hashmap field
144     # replicating some of the matches in the flows section. Same comment applies for further keywords.
145     IF    '${ODL_OF_PLUGIN}' == 'helium'
146         Set Test Variable    &{dictionary}    10.0.1.0/24=2    "output-node-connector":"1"=1
147     END
148     IF    '${ODL_OF_PLUGIN}' == 'lithium'
149         Set Test Variable    &{dictionary}    10.0.1.0/24=1    "output-node-connector":"1"=1
150     END
151     ClusterManagement.Put_As_Json_And_Check_Member_List_Or_All
152     ...    ${config_table_0}/flow=1
153     ...    ${body}
154     ...    ${controller_index}
155     ...    ${controller_index_list}
156     Wait Until Keyword Succeeds
157     ...    15s
158     ...    1s
159     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
160     ...    uri=${operational_table_0}
161     ...    dictionary=${dictionary}
162     ...    member_index_list=${controller_index_list}
163
164 Verify Sample Flow
165     [Documentation]    Verify sample flow gets applied in all instances in ${controller_index_list}.
166     [Arguments]    ${controller_index_list}=${EMPTY}
167     # There are slight differences on the way He and Li plugin display table information. He plugin has an additional Hashmap field
168     # replicating some of the matches in the flows section. Same comment applies for further keywords.
169     IF    '${ODL_OF_PLUGIN}' == 'helium'
170         Set Test Variable    &{dictionary}    10.0.1.0/24=2    "output-node-connector":"1"=1
171     END
172     IF    '${ODL_OF_PLUGIN}' == 'lithium'
173         Set Test Variable    &{dictionary}    10.0.1.0/24=1    "output-node-connector":"1"=1
174     END
175     Wait Until Keyword Succeeds
176     ...    15s
177     ...    1s
178     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
179     ...    uri=${operational_table_0}
180     ...    dictionary=${dictionary}
181     ...    member_index_list=${controller_index_list}
182
183 Modify Sample Flow And Verify
184     [Documentation]    Modify sample flow in ${controller_index} and verify it gets applied in all instances in ${controller_index_list}.
185     [Arguments]    ${controller_index}    ${controller_index_list}=${EMPTY}
186     ${body}=    OperatingSystem.Get File    ${CURDIR}/../variables/openflowplugin/sample_flow_2.json
187     IF    '${ODL_OF_PLUGIN}' == 'helium'
188         Set Test Variable    &{dictionary}    10.0.1.0/24=2    "output-node-connector":"2"=1
189     END
190     IF    '${ODL_OF_PLUGIN}' == 'lithium'
191         Set Test Variable    &{dictionary}    10.0.1.0/24=1    "output-node-connector":"2"=1
192     END
193     ClusterManagement.Put_As_Json_And_Check_Member_List_Or_All
194     ...    ${config_table_0}/flow=1
195     ...    ${body}
196     ...    ${controller_index}
197     ...    ${controller_index_list}
198     Wait Until Keyword Succeeds
199     ...    15s
200     ...    1s
201     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
202     ...    uri=${operational_table_0}
203     ...    dictionary=${dictionary}
204     ...    member_index_list=${controller_index_list}
205
206 Delete Sample Flow And Verify
207     [Documentation]    Delete sample flow in Owner and verify it gets removed from all instances.
208     [Arguments]    ${controller_index}    ${controller_index_list}=${EMPTY}
209     ${dictionary}=    Create Dictionary    10.0.1.0/24=0
210     ClusterManagement.Delete_And_Check_Member_List_Or_All
211     ...    ${config_table_0}/flow=1
212     ...    ${controller_index}
213     ...    ${controller_index_list}
214     Wait Until Keyword Succeeds
215     ...    5s
216     ...    1s
217     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
218     ...    uri=${operational_table_0}
219     ...    dictionary=${dictionary}
220     ...    member_index_list=${controller_index_list}
221
222 Send RPC Add Sample Flow And Verify
223     [Documentation]    Add sample flow in ${controller_index} and verify it gets applied from all instances in ${controller_index_list}.
224     [Arguments]    ${controller_index}    ${controller_index_list}=${EMPTY}
225     ${body}=    OperatingSystem.Get File    ${CURDIR}/../variables/openflowplugin/add_flow_rpc.json
226     IF    '${ODL_OF_PLUGIN}' == 'helium'
227         Set Test Variable    &{dictionary}    10.0.1.0/24=2
228     END
229     IF    '${ODL_OF_PLUGIN}' == 'lithium'
230         Set Test Variable    &{dictionary}    10.0.1.0/24=1
231     END
232     ClusterManagement.Post_As_Json_To_Member
233     ...    uri=/rests/operations/sal-flow:add-flow
234     ...    data=${body}
235     ...    member_index=${controller_index}
236     Wait Until Keyword Succeeds
237     ...    15s
238     ...    1s
239     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
240     ...    uri=${operational_table_0}
241     ...    dictionary=${dictionary}
242     ...    member_index_list=${controller_index_list}
243
244 Send RPC Delete Sample Flow And Verify
245     [Documentation]    Delete sample flow in ${controller_index} and verify it gets removed from all instances in ${controller_index_list}.
246     [Arguments]    ${controller_index}    ${controller_index_list}=${EMPTY}
247     ${body}=    OperatingSystem.Get File    ${CURDIR}/../variables/openflowplugin/delete_flow_rpc.json
248     ${dictionary}=    Create Dictionary    10.0.1.0/24=0
249     ClusterManagement.Post_As_Json_To_Member
250     ...    uri=/rests/operations/sal-flow:remove-flow
251     ...    data=${body}
252     ...    member_index=${controller_index}
253     Wait Until Keyword Succeeds
254     ...    5s
255     ...    1s
256     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
257     ...    uri=${operational_table_0}
258     ...    dictionary=${dictionary}
259     ...    member_index_list=${controller_index_list}
260
261 Take OpenFlow Device Link Down and Verify
262     [Documentation]    Take a link down and verify port status in all instances in ${controller_index_list}.
263     [Arguments]    ${controller_index_list}=${EMPTY}
264     ${dictionary}=    Create Dictionary    "link-down":true=1
265     ${ouput}=    MininetKeywords.Send Mininet Command    ${mininet_conn_id}    link s1 s2 down
266     Wait Until Keyword Succeeds
267     ...    5s
268     ...    1s
269     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
270     ...    uri=${operational_port_1}
271     ...    dictionary=${dictionary}
272     ...    member_index_list=${controller_index_list}
273     ${dictionary}=    Create Dictionary    openflow:1=16    openflow:2=14    openflow:3=19
274     Wait Until Keyword Succeeds
275     ...    20s
276     ...    2s
277     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
278     ...    uri=${RFC8040_OPERATIONAL_TOPO_API}
279     ...    dictionary=${dictionary}
280     ...    member_index_list=${controller_index_list}
281
282 Take OpenFlow Device Link Up and Verify
283     [Documentation]    Take the link up and verify port status in all instances in ${controller_index_list}.
284     [Arguments]    ${controller_index_list}=${EMPTY}
285     ${dictionary}=    Create Dictionary    "link-down":true=0
286     ${ouput}=    MininetKeywords.Send Mininet Command    ${mininet_conn_id}    link s1 s2 up
287     Wait Until Keyword Succeeds
288     ...    5s
289     ...    1s
290     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
291     ...    uri=${operational_port_1}
292     ...    dictionary=${dictionary}
293     ...    member_index_list=${controller_index_list}
294     ${dictionary}=    Create Dictionary    openflow:1=21    openflow:2=19    openflow:3=19
295     Wait Until Keyword Succeeds
296     ...    10s
297     ...    1s
298     ...    ClusterManagement.Check_Item_Occurrence_Member_List_Or_All
299     ...    uri=${RFC8040_OPERATIONAL_TOPO_API}
300     ...    dictionary=${dictionary}
301     ...    member_index_list=${controller_index_list}
302
303 Verify Switch Connections Running On Member
304     [Documentation]    Check if number of Switch connections on member of given index is equal to ${switch_count}.
305     [Arguments]    ${switch_count}    ${member_index}
306     ${count}=    ScaleClient.Get_Switches_Count    controller=${ODL_SYSTEM_${member_index}_IP}
307     BuiltIn.Should_Be_Equal_As_Numbers    ${switch_count}    ${count}
308
309 Check Flows Operational Datastore On Member
310     [Documentation]    Check if number of Operational Flows on member of given index is equal to ${flow_count}.
311     [Arguments]    ${flow_count}    ${member_index}
312     ${sw}    ${reported_flow}    ${found_flow}=    ScaleClient.Flow Stats Collected
313     ...    controller=${ODL_SYSTEM_${member_index}_IP}
314     BuiltIn.Should_Be_Equal_As_Numbers    ${flow_count}    ${found_flow}
315
316 Check Linear Topology On Member
317     [Documentation]    Check Linear topology.
318     [Arguments]    ${switches}    ${member_index}=1
319     ${session}=    Resolve_Http_Session_For_Member    member_index=${member_index}
320     ${resp}=    RequestsLibrary.Get Request    ${session}    ${RFC8040_OPERATIONAL_TOPO_API}
321     Log    ${resp.text}
322     Should Be Equal As Strings    ${resp.status_code}    200
323     FOR    ${switch}    IN RANGE    1    ${switches+1}
324         Should Contain    ${resp.text}    "node-id":"openflow:${switch}"
325         Should Contain    ${resp.text}    "tp-id":"openflow:${switch}:1"
326         Should Contain    ${resp.text}    "tp-id":"openflow:${switch}:2"
327         Should Contain    ${resp.text}    "source-tp":"openflow:${switch}:2"
328         Should Contain    ${resp.text}    "dest-tp":"openflow:${switch}:2"
329         ${edge}=    Evaluate    ${switch}==1 or ${switch}==${switches}
330         IF    not ${edge}
331             Should Contain    ${resp.text}    "tp-id":"openflow:${switch}:3"
332         END
333         IF    not ${edge}
334             Should Contain    ${resp.text}    "source-tp":"openflow:${switch}:3"
335         END
336         IF    not ${edge}
337             Should Contain    ${resp.text}    "dest-tp":"openflow:${switch}:3
338         END
339     END
340
341 Check No Switches On Member
342     [Documentation]    Check no switch is in topology
343     [Arguments]    ${switches}    ${member_index}=1
344     ${session}=    Resolve_Http_Session_For_Member    member_index=${member_index}
345     ${resp}=    RequestsLibrary.Get Request    ${session}    ${RFC8040_OPERATIONAL_TOPO_API}
346     Log    ${resp.text}
347     Should Be Equal As Strings    ${resp.status_code}    200
348     FOR    ${switch}    IN RANGE    1    ${switches+1}
349         Should Not Contain    ${resp.text}    openflow:${switch}
350     END
351
352 Check Number Of Flows On Member
353     [Documentation]    Check number of flows in the inventory.
354     [Arguments]    ${flows}    ${member_index}=1
355     ${session}=    Resolve_Http_Session_For_Member    member_index=${member_index}
356     ${resp}=    RequestsLibrary.Get Request    ${session}    ${RFC8040_OPERATIONAL_NODES_API}
357     Log    ${resp.text}
358     Should Be Equal As Strings    ${resp.status_code}    200
359     ${count}=    Get Count    ${resp.text}    "priority"
360     Should Be Equal As Integers    ${count}    ${flows}
361
362 Check Number Of Groups On Member
363     [Documentation]    Check number of groups in the inventory.
364     [Arguments]    ${groups}    ${member_index}=1
365     ${session}=    Resolve_Http_Session_For_Member    member_index=${member_index}
366     ${resp}=    RequestsLibrary.Get Request    ${session}    ${RFC8040_OPERATIONAL_NODES_API}
367     Log    ${resp.text}
368     Should Be Equal As Strings    ${resp.status_code}    200
369     ${group_count}=    Get Count    ${resp.text}    "group-type"
370     Should Be Equal As Integers    ${group_count}    ${groups}