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