Documentation Keywords used to create/modify flow objects. The object is defined in the
... corresponding FlowLib.py library and contains pertinent fields and methods (e.g.,
... cookie and barrier fields, string formatted xml that can be used to push to
-... controller)
+... controller). TODO: Remove hard dependency on controller HTTP "session".
Library XML
+Library String
Library RequestsLibrary
-Library ./FlowLib.py
-Library ./XmlComparator.py
-Library ./Common.py
+Library ScaleClient.py
+Library FlowLib.py
+Library XmlComparator.py
+Library Common.py
Variables ../variables/Variables.py
-*** Variables ***
-
*** Keywords ***
+Check No Switches In Inventory
+ [Arguments] ${switches}
+ [Documentation] Check no switch is in inventory
+ ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
+ Log ${resp.text}
+ FOR ${switch} IN RANGE 1 ${switches+1}
+ Should Not Contain ${resp.text} "openflow:${switch}"
+ END
+
+Check No Switches In Topology
+ [Arguments] ${switches}
+ [Documentation] Check no switch is in topology
+ ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
+ Log ${resp.text}
+ Should Be Equal As Strings ${resp.status_code} 200
+ FOR ${switch} IN RANGE 1 ${switches+1}
+ Should Not Contain ${resp.text} openflow:${switch}
+ END
+
+Check Switches In Inventory
+ [Arguments] ${switches}
+ [Documentation] Check all switches and stats in operational inventory
+ FOR ${switch} IN RANGE 1 ${switches+1}
+ ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}/node/openflow:${switch}
+ Log ${resp.text}
+ Should Be Equal As Strings ${resp.status_code} 200
+ Should Contain ${resp.text} flow-capable-node-connector-statistics
+ Should Contain ${resp.text} flow-table-statistics
+ END
+
+Check Switches In Topology
+ [Arguments] ${switches}
+ [Documentation] Check switches are in the topology.
+ ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
+ Log ${resp.text}
+ Should Be Equal As Strings ${resp.status_code} 200
+ ${count}= Get Count ${resp.text} "node-id":"openflow:
+ BuiltIn.Should Be Equal As Numbers ${count} ${switches}
+
+Check Number Of Links
+ [Arguments] ${links}
+ [Documentation] Check number of links in the topolgy.
+ ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
+ Log ${resp.text}
+ Should Be Equal As Strings ${resp.status_code} 200
+ ${count}= Get Count ${resp.text} "link-id":"openflow:
+ Should Be Equal As Integers ${count} ${links}
+
+Check Linear Topology
+ [Arguments] ${switches}
+ [Documentation] Check Linear topology.
+ ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
+ Log ${resp.text}
+ Should Be Equal As Strings ${resp.status_code} 200
+ FOR ${switch} IN RANGE 1 ${switches+1}
+ Should Contain ${resp.text} "node-id":"openflow:${switch}"
+ Should Contain ${resp.text} "tp-id":"openflow:${switch}:1"
+ Should Contain ${resp.text} "tp-id":"openflow:${switch}:2"
+ Should Contain ${resp.text} "source-tp":"openflow:${switch}:2"
+ Should Contain ${resp.text} "dest-tp":"openflow:${switch}:2"
+ ${edge} Evaluate ${switch}==1 or ${switch}==${switches}
+ Run Keyword Unless ${edge} Should Contain ${resp.text} "tp-id":"openflow:${switch}:3"
+ Run Keyword Unless ${edge} Should Contain ${resp.text} "source-tp":"openflow:${switch}:3"
+ Run Keyword Unless ${edge} Should Contain ${resp.text} "dest-tp":"openflow:${switch}:3"
+ END
+
+Check Flows Operational Datastore
+ [Arguments] ${flow_count} ${controller_ip}=${ODL_SYSTEM_IP}
+ [Documentation] Check if number of Operational Flows on member of given index is equal to ${flow_count}.
+ ${sw} ${reported_flow} ${found_flow}= ScaleClient.Flow Stats Collected controller=${controller_ip}
+ Should_Be_Equal_As_Numbers ${flow_count} ${found_flow}
+
+Check Number Of Flows
+ [Arguments] ${flows}
+ [Documentation] Check number of flows in the inventory.
+ ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
+ Log ${resp.text}
+ Should Be Equal As Strings ${resp.status_code} 200
+ ${count}= Get Count ${resp.text} "priority"
+ Should Be Equal As Integers ${count} ${flows}
+
+Check Number Of Groups
+ [Arguments] ${groups}
+ [Documentation] Check number of groups in the inventory.
+ ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
+ Log ${resp.text}
+ Should Be Equal As Strings ${resp.status_code} 200
+ ${group_count}= Get Count ${resp.text} "group-type"
+ Should Be Equal As Integers ${group_count} ${groups}
+
Check Flow Stats Are Available
[Arguments] ${node_id} ${flows}
[Documentation] A GET on the /node/${node_id} inventory API is made and flow stats string is checked for existence.
${resp} RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}/node/${node_id}/table/2
- Log ${resp.content}
+ Log ${resp.text}
+ Should Be Equal As Strings ${resp.status_code} 200
+ Should Contain X Times ${resp.text} priority ${flows}
+
+Check Number Of Hosts
+ [Arguments] ${hosts}
+ [Documentation] Check number of hosts in topology
+ ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
+ Log ${resp.text}
+ Should Be Equal As Strings ${resp.status_code} 200
+ ${count}= Get Count ${resp.text} "node-id":"host:
+ Should Be Equal As Integers ${count} ${hosts}
+
+Check No Hosts
+ [Documentation] Check if all hosts are deleted from inventory
+ ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
Should Be Equal As Strings ${resp.status_code} 200
- Should Contain X Times ${resp.content} priority ${flows}
+ Should Not Contain ${resp.text} "node-id":"host:
+
+Add Table Miss Flows
+ [Arguments] ${switches}
+ [Documentation] Add table miss flows to switches.
+ ${switches}= Convert To Integer ${switches}
+ ${data}= OperatingSystem.Get File ${CURDIR}/../variables/openflowplugin/table_miss_flow.json
+ FOR ${switch} IN RANGE 1 ${switches+1}
+ TemplatedRequests.Put As Json To Uri ${CONFIG_NODES_API}/node/openflow:${switch}/table/0/flow/default ${data} session
+ END
+
+Check Table Miss Flows
+ [Arguments] ${switches}
+ [Documentation] Check table miss flows in switches.
+ ${switches}= Convert To Integer ${switches}
+ FOR ${switch} IN RANGE 1 ${switches+1}
+ TemplatedRequests.Get As Json From Uri ${OPERATIONAL_NODES_API}/node/openflow:${switch}/table/0/flow/default session
+ END
Create Inventory Flow
[Documentation] Calls FlowLib.Make_Inventory_Flow function and initializes and sanitizes
[Arguments] ${group_body} ${node_id} ${group_id}
[Documentation] Push group through REST-API and verify in data-store
${resp} RequestsLibrary.Put Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id} headers=${HEADERS_XML} data=${group_body}
- Log ${resp.content}
+ Log ${resp.text}
BuiltIn.Should_Match "${resp.status_code}" "20?"
${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id} headers=${ACCEPT_XML}
- Log ${resp.content}
+ Log ${resp.text}
Should Be Equal As Strings ${resp.status_code} 200
- Compare Xml ${group_body} ${resp.content}
+ Compare Xml ${group_body} ${resp.text}
Add Flow To Controller And Verify
[Arguments] ${flow_body} ${node_id} ${table_id} ${flow_id}
[Documentation] Push flow through REST-API and verify in data-store
${resp} RequestsLibrary.Put Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id} headers=${HEADERS_XML} data=${flow_body}
- Log ${resp.content}
+ Log ${resp.text}
BuiltIn.Should_Match "${resp.status_code}" "20?"
${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id} headers=${ACCEPT_XML}
- Log ${resp.content}
+ Log ${resp.text}
Should Be Equal As Strings ${resp.status_code} 200
- Compare Xml ${flow_body} ${resp.content}
+ Compare Xml ${flow_body} ${resp.text}
Verify Flow On Mininet Switch
[Arguments] ${flow_elements}
Sleep 1
Write dpctl dump-flows -O OpenFlow13
${switchoutput} Read Until >
- : FOR ${flowElement} IN @{flow_elements}
- \ Should Contain ${switchoutput} ${flowElement}
+ FOR ${flowElement} IN @{flow_elements}
+ Should Contain ${switchoutput} ${flowElement}
+ END
Remove Group From Controller And Verify
[Arguments] ${node_id} ${group_id}
[Documentation] Remove group and verify
${resp} RequestsLibrary.Delete Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id}
- Log ${resp.content}
+ Log ${resp.text}
Should Be Equal As Strings ${resp.status_code} 200
${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/group/${group_id}
- Builtin.Return_From_Keyword_If ${resp.status_code} == 404
+ Builtin.Return_From_Keyword_If ${resp.status_code} == 404 or ${resp.status_code} == 409
Builtin.Log ${resp.text}
Builtin.Fail The request failed with code ${resp.status_code}
[Arguments] ${node_id} ${table_id} ${flow_id}
[Documentation] Remove flow and verify
${resp} RequestsLibrary.Delete Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id}
- Log ${resp.content}
+ Log ${resp.text}
Should Be Equal As Strings ${resp.status_code} 200
${resp} RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id}
- Builtin.Return_From_Keyword_If ${resp.status_code} == 404
+ Builtin.Return_From_Keyword_If ${resp.status_code} == 404 or ${resp.status_code} == 409
Builtin.Log ${resp.text}
Builtin.Fail The request failed with code ${resp.status_code}
Sleep 1
Write dpctl dump-flows -O OpenFlow13
${switchoutput} Read Until >
- : FOR ${flowElement} IN @{flow_elements}
- \ Should Not Contain ${switchoutput} ${flowElement}
+ FOR ${flowElement} IN @{flow_elements}
+ Should Not Contain ${switchoutput} ${flowElement}
+ END
Remove Default Flows
[Arguments] ${node_id}
${switchoutput} Read Until >
${headers}= Create Dictionary Content-Type=application/yang.data+xml
${resp} RequestsLibrary.Post Request session restconf/operations/sal-flow:remove-flow data=${flow.xml} headers=${headers}
- Log ${resp.content}
+ Log ${resp.text}
Should Be Equal As Strings ${resp.status_code} 200
${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
- Log ${resp.content}
- Should Not Contain ${resp.content} "output-node-connector": "CONTROLLER",
+ Log ${resp.text}
+ Should Not Contain ${resp.text} "output-node-connector": "CONTROLLER",
${strings_to_check_for}= Create List CONTROLLER
Verify Flow Does Not Exist On Mininet Switch ${strings_to_check_for}
Create Flow Variables For Suite From XML File ${XmlsDir}/${fname}
# Note: ${upddata} and ${data} are suite variables set by the keyword above.
${det}= Set Variable If ${upd}==${True} ${upddata} ${data}
+ Log ${det}
Check Config Flow ${reqconfpres} ${det}
Check Operational Flow ${reqoperpres} ${det} ${check_id}
${headers}= Create Dictionary Accept=application/xml
${resp}= RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/openflow:${switch_idx}/table/${table_id}/flow/${flow_id} headers=${headers}
Log ${resp}
- Log ${resp.content}
+ Log ${resp.text}
Return From Keyword If ${resp.status_code}!=200 ${False} ${EMPTY}
- ${pres} ${msg}= Is Flow Configured ${expvalue} ${resp.content}
+ ${pres} ${msg}= Is Flow Configured ${expvalue} ${resp.text}
Run Keyword If '''${msg}'''!='${EMPTY}' Log ${msg}
Return From Keyword ${pres} ${msg}
${headers}= Create Dictionary Accept=application/xml
${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}/node/openflow:${switch_idx}/table/${table_id} headers=${headers}
Log ${resp}
- Log ${resp.content}
+ Log ${resp.text}
Return From Keyword If ${resp.status_code}!=200 ${False} ${EMPTY}
- ${pres} ${msg}= Is Flow Operational2 ${expvalue} ${resp.content} ${check_id}
+ ${pres} ${msg}= Is Flow Operational2 ${expvalue} ${resp.text} ${check_id}
Run Keyword If '''${msg}'''!='${EMPTY}' Log ${msg}
Return From Keyword ${pres} ${msg}
Log Element ${req}
${strxml}= Element To String ${req}
${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:add-flow data=${strxml}
- Log ${resp.content}
+ Log ${resp.text}
Should Be Equal As Strings ${resp.status_code} 200
Add Flow Via Restconf
[Documentation] Configures a flow specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using POST method
Log ${flow_body}
${resp}= RequestsLibrary.Post Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} data=${flow_body}
- Log ${resp.content}
+ Log ${resp.text}
${msg}= Set Variable Adding flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} failed, http response ${resp.status_code} received.
Should Be Equal As Strings ${resp.status_code} 204 msg=${msg}
Log Element ${xml}
${strxml}= Element To String ${xml}
${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:update-flow data=${strxml}
- Log ${resp.content}
+ Log ${resp.text}
Should Be Equal As Strings ${resp.status_code} 200
Update Flow Via Restconf
[Documentation] Updates a flow configuration by given flow details (${node_id}, ${table_id}, ${flow_body}) using PUT method
Log ${flow_body}
${resp}= RequestsLibrary.Put Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} data=${flow_body}
- Log ${resp.content}
+ Log ${resp.text}
${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.
Should Be Equal As Strings ${resp.status_code} 200 msg=${msg}
Log Element ${req}
${strxml}= Element To String ${req}
${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:remove-flow data=${strxml}
- Log ${resp.content}
+ Log ${resp.text}
Should Be Equal As Strings ${resp.status_code} 200
Delete Flow Via Restconf
[Arguments] ${node_id} ${table_id} ${flow_id}
[Documentation] Deletes a flow from configuration datastore specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using DELETE method
${resp}= RequestsLibrary.Delete Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id}
- Log ${resp.content}
+ Log ${resp.text}
${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.
Should Be Equal As Strings ${resp.status_code} 200 msg=${msg}
+
+Get Flow Id
+ [Arguments] ${dpnid} ${table_id} ${flow_element}
+ [Documentation] This verifies specific flow-id for particular table-id matching from the flow element
+ ${resp} = RequestsLibrary.Get Request session ${CONFIG_NODES_API}/node/openflow:${dpnid}/table/${table_id}
+ BuiltIn.Log ${resp.text}
+ @{flow_id} = String.Get Regexp Matches ${resp.text} id\":\"(\\d+${flow_element}) 1
+ [Return] @{flow_id}[0]