ffccd72aeeb53e8209ed3585d5d36bdeb40af4b4
[integration/test.git] / test / csit / libraries / FlowLib.robot
1 *** Settings ***
2 Documentation     Keywords used to create/modify flow objects. The object is defined in the
3 ...               corresponding FlowLib.py library and contains pertinent fields and methods (e.g.,
4 ...               cookie and barrier fields, string formatted xml that can be used to push to
5 ...               controller)
6 Library           ./FlowLib.py
7 Library           XML
8 Library           RequestsLibrary
9 Variables         ../variables/Variables.py
10
11 *** Variables ***
12
13 *** Keywords ***
14 Create Inventory Flow
15     [Documentation]    Calls FlowLib.Make_Inventory_Flow function and initializes and sanitizes
16     ...    the basic flow elements that can be given to flow:inventory
17     ${flow}=    Make Inventory Flow
18     [Return]    ${flow}
19
20 Create Service Flow
21     [Documentation]    Used for creating an object that will use an XML format that
22     ...    can be given to flow:service.
23     ${flow}=    Make Service Flow
24     [Return]    ${flow}
25
26 Set "${flow}" "${property}" With "${property_val}"
27     [Documentation]    Embedded variables to make higher level keywords more readable.
28     ...    There are some cases where the python attribute uses an underscore,
29     ...    but a hyphen needs to be used. This seems inconsistent, and may need
30     ...    to be looked at from the openflow plugin perspective.
31     ...
32     ...    At this point, this library will remove the element ${property} from the
33     ...    xml representation of the flow and reset with the given value. \ It's not
34     ...    possible, yet, to have multiple elements with the same name. \ That will
35     ...    likely be needed in the future.
36     ${property}    Run Keyword If    "table_id" != "${property}" and "cookie_mask" != "${property}"    Replace String    ${property}    _    -
37     ...    ELSE    Set Variable    ${property}
38     Remove Flow XML Element    ${flow}    ${property}
39     Add Flow XML Element    ${flow}    ${property}    ${property_val}
40     Set Flow Field    ${flow}    ${property}    ${property_val}
41     [Return]    ${flow}
42
43 Set Flow Action
44     [Arguments]    ${flow}    ${instruction_order}    ${action_order}    ${action}    ${action_val}=${EMPTY}
45     [Documentation]    Will remove the instruction element first, then add the proper xml structure
46     ...    to implement the action as given in the arguments
47     ##For the case that any of the instruction/apply-actions/action elements are not there we need to add them'
48     Remove Flow XML Element    ${flow}    instruction
49     Add Flow XML Element    ${flow}    instruction    ${EMPTY}    instructions
50     Add Flow XML Element    ${flow}    order    ${instruction_order}    instructions/instruction
51     Add Flow XML Element    ${flow}    apply-actions    ${EMPTY}    instructions/instruction
52     Add Flow XML Element    ${flow}    action    ${EMPTY}    instructions/instruction/apply-actions
53     Add Flow XML Element    ${flow}    order    ${action_order}    instructions/instruction/apply-actions/action
54     Add Flow XML Element    ${flow}    ${action}    ${action_val}    instructions/instruction/apply-actions/action
55     [Return]    ${flow}
56
57 Set Flow Output Action
58     [Arguments]    ${flow}    ${instruction_order}    ${action_order}    ${output_port}
59     Set Flow Action    ${flow}    ${instruction_order}    ${action_order}    output-action
60     Add Flow XML Element    ${flow}    output-node-connector    ${output_port}    instructions/instruction/apply-actions/action/output-action
61     [Return]    ${flow}
62
63 Set Flow Ethernet Match
64     [Arguments]    ${flow}    ${match_value_dict}
65     [Documentation]    Specific keyword for adding an ethernet match rules where the elements are given
66     ...    in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
67     ...    existing ethernet-match elements from the flow before adding
68     Clear Flow Matches    ${flow}    match/ethernet-match
69     Add Flow XML Element    ${flow}    ethernet-match    ${EMPTY}    match
70     ${type}=    Get From Dictionary    ${match_value_dict}    type
71     Add Flow XML Element    ${flow}    ethernet-type    ${EMPTY}    match/ethernet-match
72     Add Flow XML Element    ${flow}    type    ${type}    match/ethernet-match/ethernet-type
73     ${src}=    Get From Dictionary    ${match_value_dict}    source
74     Add Flow XML Element    ${flow}    ethernet-source    ${EMPTY}    match/ethernet-match
75     Add Flow XML Element    ${flow}    address    ${src}    match/ethernet-match/ethernet-source
76     ${dst}=    Get From Dictionary    ${match_value_dict}    destination
77     Add Flow XML Element    ${flow}    ethernet-destination    ${EMPTY}    match/ethernet-match
78     Add Flow XML Element    ${flow}    address    ${dst}    match/ethernet-match/ethernet-destination
79     [Return]    ${flow}
80
81 Set Flow IPv4 Match
82     [Arguments]    ${flow}    ${match_value_dict}
83     [Documentation]    Specific keyword for adding an ipv4 match rules where the elements are given
84     ...    in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
85     ...    existing ipv4 match elements from the flow before adding
86     Clear Flow Matches    ${flow}    match/ipv4-source
87     Clear Flow Matches    ${flow}    match/ipv4-destination
88     ${src}=    Get From Dictionary    ${match_value_dict}    source
89     Add Flow XML Element    ${flow}    ipv4-source    ${src}    match
90     ${dst}=    Get From Dictionary    ${match_value_dict}    destination
91     Add Flow XML Element    ${flow}    ipv4-destination    ${dst}    match
92     [Return]    ${flow}
93
94 Clear Flow Actions
95     [Arguments]    ${flow}
96     [Documentation]    Will clean out any existing flow actions in the given ${flow} object
97     Remove Flow XML Element    ${flow}    instructions/instruction
98     [Return]    ${flow}
99
100 Clear Flow Matches
101     [Arguments]    ${flow}    ${match_element}
102     [Documentation]    Will clean out any existing flow matches in the given ${flow} object
103     Remove Flow XML Element    ${flow}    match/${match_element}
104     [Return]    ${flow}
105
106 Set Flow XML Element Attribute
107     [Arguments]    ${flow}    ${element}    ${id}    ${value}
108     [Documentation]    Will set the given id/value pair to the given to the element provided
109     ...    and make the proper changes to the ${flow} object also provided.
110     ${flow_xml}=    Parse XML    ${flow.xml}
111     Set Element Attribute    ${flow_xml}    ${id}    ${value}    xpath=${element}
112     ${xml_string}=    Element To String    ${flow_xml}
113     Set Flow Field    ${flow}    xml    ${xml_string}
114     Log    ${flow.xml}
115     [Return]    ${flow}
116
117 Add Flow XML Element
118     [Arguments]    ${flow}    ${element}    ${element_val}=${EMPTY}    ${xpath}=.
119     [Documentation]    Will modify the current xml representation of the ${flow} object to contain
120     ...    the given ${element} at the given ${xpath}. If the ${element} uses a value, that can be
121     ...    passed eith the ${element_val} which defaults to ${EMPTY} if not used. NOTE: since there
122     ...    are two default parameters to this keyword, if you have an ${xpath} to use, but no ${element_val}
123     ...    you will still need to pass ${EMPTY} when invoking so that ${xpath} will end up at the right
124     ...    location in the parameter list
125     ${flow_xml}=    Parse XML    ${flow.xml}
126     Add Element    ${flow_xml}    <${element}>${element_val}</${element}>    xpath=${xpath}
127     ${xml_string}=    Element To String    ${flow_xml}
128     Set Flow Field    ${flow}    xml    ${xml_string}
129     Log    ${flow.xml}
130     [Return]    ${flow}
131
132 Remove Flow XML Element
133     [Arguments]    ${flow}    ${element_xpath}
134     [Documentation]    Removes the element at the given ${element_xpath} within the given ${flow}
135     ...    object. The ${flow} object's xml representation will be updated to reflect this removal.
136     ${flow_xml}=    Parse XML    ${flow.xml}
137     Run Keyword And Ignore Error    Remove Elements    ${flow_xml}    xpath=${element_xpath}
138     ${xml_string}=    Element To String    ${flow_xml}
139     Set Flow Field    ${flow}    xml    ${xml_string}
140     [Return]    ${flow}
141
142 Add Flow To Controller And Verify
143     [Arguments]    ${flow_body}    ${node_id}    ${table_id}    ${flow_id}
144     [Documentation]    Push flow through REST-API and verify in data-store
145     ${resp}    RequestsLibrary.Put    session    ${REST_CON}/node/${node_id}/table/${table_id}/flow/${flow_id}    headers=${HEADERS_XML}    data=${flow_body}
146     Log    ${resp.content}
147     Should Be Equal As Strings    ${resp.status_code}    200
148     ${resp}    RequestsLibrary.Get    session    ${REST_CON}/node/${node_id}/table/${table_id}/flow/${flow_id}    headers=${ACCEPT_XML}
149     Log    ${resp.content}
150     Should Be Equal As Strings    ${resp.status_code}    200
151     compare xml    ${flow_body}    ${resp.content}
152
153 Verify Flow On Mininet Switch
154     [Arguments]    ${flow_elements}
155     [Documentation]    Checking flow on switch
156     sleep    1
157     write    dpctl dump-flows -O OpenFlow13
158     ${switchoutput}    Read Until    >
159     : FOR    ${flowElement}    IN    @{flow_elements}
160     \    should Contain    ${switchoutput}    ${flowElement}
161
162 Remove Flow From Controller And Verify
163     [Arguments]    ${flow_body}    ${node_id}    ${table_id}    ${flow_id}
164     [Documentation]    Remove flow
165     ${resp}    RequestsLibrary.Delete    session    ${REST_CON}/node/${node_id}/table/${table_id}/flow/${flow_id}
166     Log    ${resp.content}
167     Should Be Equal As Strings    ${resp.status_code}    200
168     ${resp}    RequestsLibrary.Get    session    ${REST_CON}/node/${node_id}/table/${table_id}
169     Log    ${resp.content}
170     Should Not Contain    ${resp.content}    ${flow_id}
171
172 Verify Flow Does Not Exist On Mininet Switch
173     [Arguments]    ${flow_elements}
174     [Documentation]    Checking flow on switch is removed
175     sleep    1
176     write    dpctl dump-flows -O OpenFlow13
177     ${switchoutput}    Read Until    >
178     : FOR    ${flowElement}    IN    @{flow_elements}
179     \    should Not Contain    ${switchoutput}    ${flowElement}
180
181 Remove Default Flows
182     [Arguments]    ${node_id}
183     [Documentation]    Removes any flows considered "default". one such flow is
184     ...    to forward all traffic to the CONTROLLER with priority 0 at flow-table 0
185     ...    If/When others are implemented this keyword can be updated to include those.
186     ${flow}=    Make Service Flow
187     Set "${flow}" "priority" With "0"
188     Set "${flow}" "flow-table" With "0"
189     Add Flow XML Element    ${flow}    node    /inv:nodes/inv:node[inv:id="${node_id}"]
190     Set Flow XML Element Attribute    ${flow}    node    xmlns:inv    urn:opendaylight:inventory
191     Log    Flow XML is ${flow.xml}
192     write    dpctl dump-flows -O OpenFlow13
193     ${switchoutput}    Read Until    >
194     ${headers}=    Create Dictionary    Content-Type    application/yang.data+xml
195     ${resp}    RequestsLibrary.Post    session    restconf/operations/sal-flow:remove-flow    data=${flow.xml}    headers=${headers}
196     Log    ${resp.content}
197     Should Be Equal As Strings    ${resp.status_code}    200
198     ${resp}=    RequestsLibrary.Get    session    ${OPERATIONAL_NODES_API}
199     Log    ${resp.content}
200     Should Not Contain    ${resp.content}    "output-node-connector": "CONTROLLER",
201     ${strings_to_check_for}=    Create List    CONTROLLER
202     Verify Flow Does Not Exist On Mininet Switch    ${strings_to_check_for}
203
204 Create Flow Variables For Suite From XML File
205     [Arguments]    ${file}
206     [Documentation]    Given the flow XML ${file}, it will create several suite wide variables
207     ${data}=    OperatingSystem.Get File    ${file}
208     ${xmlroot}=    Parse Xml    ${file}
209     ${table_id}=    Get Element Text    ${xmlroot}    table_id
210     ${flow_id}=    Get Element Text    ${xmlroot}    id
211     ${flow_priority}=    Get Element Text    ${xmlroot}    priority
212     ${upddata}=    Get Data For Flow Put Update    ${data}
213     Set Suite Variable    ${table_id}
214     Set Suite Variable    ${flow_id}
215     Set Suite Variable    ${flow_priority}
216     Set Suite Variable    ${data}
217     Set Suite Variable    ${upddata}
218     Set Suite Variable    ${xmlroot}
219
220 Check Datastore Presence
221     [Arguments]    ${fname}    ${reqconfpres}    ${reqoperpres}    ${upd}
222     [Documentation]    Checks if flow is properly existing or not existing in the config and operational
223     ...    datastores, based on the variables ${reqconfpres} and ${reqoperpres}
224     Create Flow Variables For Suite From XML File    ${XmlsDir}/${fname}
225     # Note:    ${upddata} and ${data} are suite variables set by the keyword above.
226     ${det}=    Set Variable If    ${upd}==${True}    ${upddata}    ${data}
227     Check Config Flow    ${reqconfpres}    ${det}
228     Check Operational Flow    ${reqoperpres}    ${det}
229
230 Flow Presence In Config Store
231     [Arguments]    ${expvalue}
232     [Documentation]    Checks the config store for given flow. Returns True if present, otherwise returns False
233     ...    This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
234     ${headers}=    Create Dictionary    Accept    application/xml
235     ${resp}=    RequestsLibrary.Get    session    ${CONFIG_NODES_API}/node/openflow:${switch_idx}/table/${table_id}/flow/${flow_id}    headers=${headers}
236     Log    ${resp}
237     Log    ${resp.content}
238     Return From Keyword If    ${resp.status_code}!=200    ${False}    ${EMPTY}
239     ${pres}    ${msg}=    Is Flow Configured    ${expvalue}    ${resp.content}
240     Run Keyword If    '''${msg}'''!='${EMPTY}'    Log    ${msg}
241     Return From Keyword    ${pres}    ${msg}
242
243 Flow Presence In Operational Store
244     [Arguments]    ${expvalue}
245     [Documentation]    Checks the operational store for given flow. Returns True if present, otherwise returns False
246     ...    This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
247     ${headers}=    Create Dictionary    Accept    application/xml
248     ${resp}=    RequestsLibrary.Get    session    ${OPERATIONAL_NODES_API}/node/openflow:${switch_idx}/table/${table_id}    headers=${headers}
249     Log    ${resp}
250     Log    ${resp.content}
251     Return From Keyword If    ${resp.status_code}!=200    ${False}    ${EMPTY}
252     ${pres}    ${msg}=    Is Flow Operational2    ${expvalue}    ${resp.content}
253     Run Keyword If    '''${msg}'''!='${EMPTY}'    Log    ${msg}
254     Return From Keyword    ${pres}    ${msg}
255
256 Get Presence Failure Message
257     [Arguments]    ${ds}    ${expected}    ${presence}    ${diffmsg}
258     [Documentation]    Utility keyword to help manipulate mesage strings that may be used later to PASS or FAIL with
259     Return From Keyword If    '''${diffmsg}'''!='${EMPTY}'    Flow found in ${ds} data store but: ${diffmsg}
260     ${msgf}=    Set Variable If    ${expected}==${True}    The flow is expected in ${ds} data store, but    The flow is not expected in ${ds} data store, but
261     ${msgp}=    Set Variable If    ${presence}==${True}    it is present.    it is not present.
262     Return From Keyword    ${msgf} ${msgp}
263
264 Check Config Flow
265     [Arguments]    ${expected}    ${expvalue}
266     [Documentation]    Wrapper keyword that calls "Flow Presence In Config Store" and "Get Presence Failure Message" from this library
267     ...    to verify that the ${expvalue} flow is or is not found in the config store, depending on whether or not it was ${expected}
268     ${presence_flow}    ${msg}=    Flow Presence In Config Store    ${expvalue}
269     ${msgf}=    Get Presence Failure Message    config    ${expected}    ${presence_flow}    ${msg}
270     Should Be Equal    ${expected}    ${presence_flow}    msg=${msgf}
271
272 Check Operational Flow
273     [Arguments]    ${expected}    ${expvalue}
274     [Documentation]    Wrapper keyword that calls "Flow Presence In Operational Store" and "Get Presence Failure Message" from this library
275     ...    to verify that the ${expvalue} flow is or is not found in the config store, depending on whether or not it was ${expected}
276     ${presence_table}    ${msg}=    Flow Presence In Operational Store    ${expvalue}
277     ${msgf}=    Get Presence Failure Message    operational    ${expected}    ${presence_table}    ${msg}
278     Should Be Equal    ${expected}    ${presence_table}    msg=${msgf}
279
280 Add Flow Via RPC
281     [Arguments]    ${node_id}    ${xmlroot}
282     [Documentation]    Deploys a flow specified by given flow details (${node_id}, ${xmlroot}) using add-flow operation.
283     ...    ${xmlroot} is an xml object of parser xml flow details, usually created by Create Flow Variables For Suite From XML File
284     ...    keyword from this library.
285     ${req}=    Copy Element    ${xmlroot}
286     Remove Element    ${req}    id    clear_tail=True
287     Set Element Tag    ${req}    input
288     Set Element Attribute    ${req}    xmlns    urn:opendaylight:flow:service
289     Add Element    ${req}    <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
290     ${nodeelm}=    Get Element    ${req}    node
291     Set Element Attribute    ${nodeelm}    xmlns:inv    urn:opendaylight:inventory
292     Log Element    ${req}
293     ${strxml}=    Element To String    ${req}
294     ${resp}=    RequestsLibrary.Post    session    /restconf/operations/sal-flow:add-flow    data=${strxml}
295     Log    ${resp.content}
296     Should Be Equal As Strings    ${resp.status_code}    200
297
298 Add Flow Via Restconf
299     [Arguments]    ${node_id}    ${table_id}    ${flow_body}
300     [Documentation]    Configures a flow specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using POST method
301     Log    ${flow_body}
302     ${resp}=    RequestsLibrary.Post    session    ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}    data=${flow_body}
303     Log    ${resp.content}
304     ${msg}=    Set Variable    Adding flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} failed, http response ${resp.status_code} received.
305     Should Be Equal As Strings    ${resp.status_code}    204    msg=${msg}
306
307 Update Flow Via RPC
308     [Arguments]    ${node_id}    ${configured_flow_body}    ${updating_flow_body}
309     [Documentation]    Updates a flow by using update-flow operation. ${xmlroot} is usually a variable created by
310     ...    Create Flow Variables For Suite From XML File keyword from this library.
311     Log    ${configured_flow_body}
312     Log    ${updating_flow_body}
313     ${xml}    Parse Xml    <input xmlns="urn:opendaylight:flow:service"></input>
314     Log Element    ${xml}
315     ${origflow}=    Parse Xml    ${configured_flow_body}
316     ${updflow}=    Parse Xml    ${updating_flow_body}
317     Remove Element    ${origflow}    id    clear_tail=True
318     Remove Element    ${updflow}    id    clear_tail=True
319     Remove Element Attribute    ${origflow}    xmlns
320     Remove Element Attribute    ${updflow}    xmlns
321     Set Element Tag    ${origflow}    original-flow
322     Set Element Tag    ${updflow}    updated-flow
323     Add Element    ${xml}    ${origflow}
324     Add Element    ${xml}    ${updflow}
325     Add Element    ${xml}    <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
326     ${nodeelm}=    Get Element    ${xml}    node
327     Set Element Attribute    ${nodeelm}    xmlns:inv    urn:opendaylight:inventory
328     Log Element    ${xml}
329     ${strxml}=    Element To String    ${xml}
330     ${resp}=    RequestsLibrary.Post    session    /restconf/operations/sal-flow:update-flow    data=${strxml}
331     Log    ${resp.content}
332     Should Be Equal As Strings    ${resp.status_code}    200
333
334 Update Flow Via Restconf
335     [Arguments]    ${node_id}    ${table_id}    ${flow_id}    ${flow_body}
336     [Documentation]    Updates a flow configuration by given flow details (${node_id}, ${table_id}, ${flow_body}) using PUT method
337     Log    ${flow_body}
338     ${resp}=    RequestsLibrary.Put    session    ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id}    data=${flow_body}
339     Log    ${resp.content}
340     ${msg}=    Set Variable    Updating flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} failed, http response ${resp.status_code} received.
341     Should Be Equal As Strings    ${resp.status_code}    200    msg=${msg}
342
343 Delete Flow Via RPC
344     [Arguments]    ${node_id}    ${xmlroot}
345     [Documentation]    Deletes a flow by using remove-flow opearation. ${xmlroot} is usually a variable created by
346     ...    Create Flow Variables For Suite From XML File keyword from this library.
347     ${req}=    Copy Element    ${xmlroot}
348     Remove Element    ${req}    id    clear_tail=True
349     Set Element Tag    ${req}    input
350     Set Element Attribute    ${req}    xmlns    urn:opendaylight:flow:service
351     Add Element    ${req}    <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
352     ${nodeelm}=    Get Element    ${req}    node
353     Set Element Attribute    ${nodeelm}    xmlns:inv    urn:opendaylight:inventory
354     Log Element    ${req}
355     ${strxml}=    Element To String    ${req}
356     ${resp}=    RequestsLibrary.Post    session    /restconf/operations/sal-flow:remove-flow    data=${strxml}
357     Log    ${resp.content}
358     Should Be Equal As Strings    ${resp.status_code}    200
359
360 Delete Flow Via Restconf
361     [Arguments]    ${node_id}    ${table_id}    ${flow_id}
362     [Documentation]    Deletes a flow from configuration datastore specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using DELETE method
363     ${resp}=    RequestsLibrary.Delete    session    ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id}
364     Log    ${resp.content}
365     ${msg}=    Set Variable    Delete flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} failed, http response ${resp.status_code} received.
366     Should Be Equal As Strings    ${resp.status_code}    200    msg=${msg}