added counters and documentation
diff --git a/Detailed_Testing_Methodology.txt b/Detailed_Testing_Methodology.txt
index a2c94e2..7b3c0b2 100644
--- a/Detailed_Testing_Methodology.txt
+++ b/Detailed_Testing_Methodology.txt
@@ -979,3 +979,459 @@
24. Sequential execution -- TBD
+
+
+
+
+**** Counters ****
+
+
+
+1. Received Packets per Flow
+
+
+Test Description: Verify that packet_count in the Flow_Stats reply increments in accordance with the packets in flow
+
+Test mode: Automated
+Test Tile: FlowCounter1
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow , match = ingress_port
+b) Send N packet matching the flow i.e packets should be sent on ingress_port
+c) Send flow_stats_request for the flow
+d) Verify packet_count = N in the flow_stats_reply
+
+
+
+2. Received Bytes per Flow
+
+
+Test Description: Verify that byte_count in the Flow_Stats reply increments in accordance with the bytes in flow
+
+Test mode: Automated
+Test Tile: FlowCounter1
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow , match = ingress_port
+b) Send N packet matching the flow i.e packets should be sent on ingress_port
+c) Send flow_stats_request for the flow
+d) Verify byte_count = N*(no. of bytes in one packet) in the flow_stats_reply
+
+
+
+3. Duration in sec per Flow
+
+
+Test Description: Verify that duration_sec in the Flow_Stats reply increments in accordance with the time that flow was alive in sec
+
+Test mode: Automated
+Test Tile: FlowCounter2
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a any flow
+b) Send flow_stats_request for that flow periodically after n sec intervals upto timeout of y
+c) Verify each flow_stats_reply has duration_sec field incrementing as n , 2n , 3n .. y
+
+
+
+4. Duration in nsec per flow
+
+
+Test Description: Verify that duration_nsec in the flow_stats repl increments in accordance with the time flow has been alive in nanoseconds
+beyond duration_sec.
+
+Test mode: Automated
+Test Tile: FlowCounter2
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert any flow
+b) Send flow_stats_request periodically after n sec intervals upto timeout of y
+c) Verify each flow_stats_reply has duration_sec field incrementing as n , 2n , 3n .. y and read out duration_nsec field ( Verification of nsec field
+is out of scope)
+
+
+
+5. Received packets per port
+
+
+Test Description: Verify that rx_packets in the Port_Stats reply increments in accordance with the packets recieved on that port
+
+Test mode: Automated
+Test Tile: PortCounter1
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match on ingress_port
+b) Send N packets on the ingress_port
+c) Send port_stats request for port=ingress_port
+d) Verify port_stats_reply has rx_packet=N
+
+
+
+
+6. Transmitted packets per port
+
+
+Test Description: Verify that tx_packets in the Port_Stats reply increments in accordance with the packets transmitted from a port
+
+Test mode: Automated
+Test Tile: PortCounter2
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match on ingress_port, action output = egress_port
+b) Send N packets on the ingress_port
+c) Send port_stats request for port=ingress_port
+d) Verify port_stats_reply had tx_packets=N
+
+
+
+7. Received Bytes per port
+
+
+Test Description: Verify that rx_bytes in the Port_Stats reply increments in accordance with the bytes recieved on a port
+
+Test mode: Automated
+Test Tile: PortCounter3
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match on ingress_port, action output = egress_port
+b) Send N packet matching the flow
+c) Send port_stats request for port=ingress_port
+d) Verify port_stats_reply had rx_bytes=N*(no. of bytes in a packet)
+
+
+
+8. Transmitted Bytes per port
+
+
+Test Description: Verify that tx_bytes in the Port_Stats reply increments in accordance with the bytes transmitted from a port
+
+Test mode: Automated
+Test Tile: PortCounter4
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match on ingress_port, action output = egress_port
+b) Send N packet matching the flow
+c) Send port_stats request for port=ingress_port
+d) Verify port_stats_reply had tx_bytes=N*(no. of bytes in a packet)
+
+
+
+9. Recieve Drops per port (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that rx_dropped counters in the Port_Stats reply increments in accordance with the packets dropped by RX
+
+Test mode: Automated
+Test Tile: RxDrops
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+Test Notes :
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has rx_dropped count
+
+
+
+
+
+10. Transmit Drops per port (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that tx_dropped counters in the Port_Stats reply increments in accordance with the packets dropped by TX
+
+Test mode: Automated
+Test Tile: TxDrops
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Manadatory
+
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has tx_dropped count
+
+
+
+
+11. Recieve Errors (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that rx_errors counters in the Port_Stats reply increments in accordance with number of recieved error
+ This is a super-set of more specific receive errors and should be greater than or equal to the sum of all
+ rx_*_err values.
+
+Test mode: Automated
+Test Tile: RxErrors
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has rx_errors count
+
+
+
+12. Transmit Errors (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that tx_errors counters in the Port_Stats reply increments in accordance with number of trasmit errors
+
+Test mode: Automated
+Test Tile: TxErrors
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has tx_errors count
+
+
+
+13. Recieve Frame Errors (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that rx_frm_err counters in the Port_Stats reply increments in accordance with the number of frame alignment errors
+Test mode: Automated
+Test Tile: RxFrameErr
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has rx_frame_err count
+
+
+
+14. Recieve Overrun Errors (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that rx_over_err counters in the Port_Stats reply increments in accordance with the number of with RX overrun
+
+Test mode: Automated
+Test Tile: RxOErr
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has rx_over_err count
+
+
+15. CRC Errors (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that rx_crc_err counters in the Port_Stats reply increments in accordance with the number of crc errors
+
+Test mode: Automated
+Test Tile: RxCrcErr
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Manadatory
+
+
+Test Notes:
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has rx_crc_err count
+
+
+
+16. Collisions (TBD ---> Verification of counter incrementing correctly)
+
+
+Test Description: Verify that collisons counters in the Port_Stats reply increments in accordance with the collisions encountered by the switch
+
+Test mode: Automated
+Test Tile: Collisions
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Send port_stats request for port=ingress_port
+b) Verify port_stats reply has collisions count
+
+
+
+17. Active Entries per Table
+
+
+Test Description: Verify that active_count in the table increments in accordance with the flows inserted in the table
+
+Test mode: Automated
+Test Tile: TableCounter1
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow
+b) Send table_stats_request
+c) Verify active_count=1
+
+
+
+18. Packet Lookup per Table
+
+
+Test Description: Verify that lookup_count in the Table_Stats reply increments in accordance with the number of packets looked up in table
+
+Test mode: Automated
+Test Tile: TableCounter2
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match on ingress_port
+b) Send N packets on ingress_port (matching the flow)
+c) Send N' packets on x port (Not matching the flow)
+d) Send table_stats_request
+e) Verify lookup_count = N+N'
+
+
+
+19. Packets matched per Table
+
+Test Description: Verify that matched_count in the Table_Stats reply increments in accordance with the number of packets matched with the table
+
+Test mode: Automated
+Test Tile: TableCounter2
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match on ingress_port
+b) Send N packets on ingress_port (matching the flow)
+c) Send N' packets on x port (Not matching the flow)
+d) Send table_stats_request
+e) Verify matched_count = N
+
+
+
+
+20. Transmit Packets per Queue
+
+Test Description: Verify that tx_packets in the queue_stats reply increments in accordance with the number of transmitted packets
+
+Test mode: Automated
+Test Tile: QueueCounter1
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+
+Test Notes:
+
+a) Send queue_stats request for ports=ofp.OFPP_ALL and queue_ids=ofp.OFPQ_ALL (i.e all ports and all queues)
+b) Send queue_stats request for egress_port[0] and queue_id[0] and note the tx_packets count in the reply
+c) Insert a flow entry with enqueue action , port = egress_port[0] queue_id= queue_id[0]
+d) Send packet matching the flow
+e) Send queue_stats request again, verify tx_packet count incremented
+f) Repeat b , c , d , e for all the queue_ids configured for egress_port[0]
+h) Repeat b , c , d , e , f for all the egress_ports available
+
+
+
+
+21. Transmit Bytes per Queue
+
+Test Description: Verify that tx_bytes in the queue_stats reply increments in accordance with the number of transmitted bytes
+
+Test mode: Automated
+Test Tile: QueueCounter2
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+
+Test Notes:
+
+a) Send queue_stats request for ports=ofp.OFPP_ALL and queue_ids=ofp.OFPQ_ALL (i.e all ports and all queues)
+b) Send queue_stats request for egress_port[0] and queue_id[0] and note the tx_bytes count in the reply
+c) Insert a flow entry with enqueue action , port = egress_port[0] queue_id= queue_id[0]
+d) Send packet matching the flow
+e) Send queue_stats request again, verify tx_byte count incremented
+f) Repeat b , c , d , e for all the queue_ids configured for egress_port[0]
+h) Repeat b , c , d , e , f for all the egress_ports available
+
+
+
+22. Transmit Overrun Errors per queue (TBD ----> Verification of tx_error count being incremented correctly)
+
+Test Description: Verify that tx_errors in the queue_stats reply increments in accordance with the number of packets dropped due to overrun.
+Test mode: Automated
+Test Tile: QueueCounter3
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Optional
+
+Test Notes:
+
+
+a) Send queue_stats request for port=egress_port and queue_ids=ofp.OFPQ_ALL
+B) send queue_stats request for egress_port and queue_id[0] (i.e first queue configured for egress_port)
+c) Verify reply has tx_errors count .
+d) Repear b , c for the all queue_ids of egress_port
\ No newline at end of file
diff --git a/tests/FuncUtils.py b/tests/FuncUtils.py
index 5cfcb6a..11ee316 100644
--- a/tests/FuncUtils.py
+++ b/tests/FuncUtils.py
@@ -12,6 +12,7 @@
import oftest.parse as parse
import logging
import types
+
import oftest.base_tests as base_tests
from oftest.testutils import *
from time import sleep
@@ -45,7 +46,35 @@
self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
return (Pkt_ExactFlow,match)
-
+
+def Exact_Match_With_Prio(self,of_ports,priority=0):
+ # Generate ExactMatch With Prority flow .
+
+ #Create a simple tcp packet and generate exact flow match from it.
+ Pkt_ExactFlow = simple_tcp_packet()
+ match = parse.packet_to_flow_match(Pkt_ExactFlow)
+ self.assertTrue(match is not None, "Could not generate flow match from pkt")
+ match.in_port = of_ports[0]
+ #match.nw_src = 1
+ match.wildcards=0
+ msg = message.flow_mod()
+ msg.out_port = ofp.OFPP_NONE
+ msg.command = ofp.OFPFC_ADD
+ msg.buffer_id = 0xffffffff
+ msg.match = match
+ if priority != 0 :
+ msg.priority = priority
+
+ act = action.action_output()
+ act.port = of_ports[2]
+ self.assertTrue(msg.actions.add(act), "could not add action")
+
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (Pkt_ExactFlow,match)
+
def Match_All_Except_Source_Address(self,of_ports,priority=0):
# Generate Match_All_Except_Source_Address flow
@@ -74,7 +103,62 @@
self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
return (Pkt_WildcardSrc,match1)
+
+def Match_Ethernet_Src_Address(self,of_ports,priority=0):
+ #Generate Match_Ethernet_SrC_Address flow
+
+ #Create a simple tcp packet and generate match on ethernet src address flow
+ pkt_MatchSrc = simple_tcp_packet(dl_src='00:01:01:01:01:01')
+ match = parse.packet_to_flow_match(pkt_MatchSrc)
+ self.assertTrue(match is not None, "Could not generate flow match from pkt")
+
+ match.wildcards = ofp.OFPFW_ALL ^ofp.OFPFW_DL_SRC
+ msg = message.flow_mod()
+ msg.out_port = ofp.OFPP_NONE
+ msg.command = ofp.OFPFC_ADD
+ msg.buffer_id = 0xffffffff
+ msg.match = match
+ if priority != 0 :
+ msg.priority = priority
+
+ act = action.action_output()
+ act.port = of_ports[1]
+ self.assertTrue(msg.actions.add(act), "could not add action")
+
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (pkt_MatchSrc,match)
+
+def Match_Ethernet_Dst_Address(self,of_ports,priority=0):
+ #Generate Match_Ethernet_Dst_Address flow
+
+ #Create a simple tcp packet and generate match on ethernet dst address flow
+ pkt_MatchDst = simple_tcp_packet(dl_dst='00:01:01:01:01:01')
+ match = parse.packet_to_flow_match(pkt_MatchDst)
+ self.assertTrue(match is not None, "Could not generate flow match from pkt")
+
+ match.wildcards = ofp.OFPFW_ALL ^ofp.OFPFW_DL_DST
+ msg = message.flow_mod()
+ msg.out_port = ofp.OFPP_NONE
+ msg.command = ofp.OFPFC_ADD
+ msg.buffer_id = 0xffffffff
+ msg.match = match
+ if priority != 0 :
+ msg.priority = priority
+
+ act = action.action_output()
+ act.port = of_ports[1]
+ self.assertTrue(msg.actions.add(act), "could not add action")
+
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (pkt_MatchDst,match)
+
def Wildcard_All(self,of_ports,priority=0):
# Generate a Wildcard_All Flow
@@ -135,7 +219,230 @@
self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
return (Pkt_MatchIngress,match3)
-
+
+def Match_Vlan_Id(self,of_ports,priority=0):
+ #Generate Match_Vlan_Id
+
+ #Create a simple tcp packet and generate match on ethernet dst address flow
+ pkt_MatchVlanId = simple_tcp_packet(dl_vlan_enable=True,dl_vlan=1)
+ match = parse.packet_to_flow_match(pkt_MatchVlanId)
+ self.assertTrue(match is not None, "Could not generate flow match from pkt")
+
+ match.wildcards = ofp.OFPFW_ALL ^ofp.OFPFW_DL_VLAN
+ msg = message.flow_mod()
+ msg.out_port = ofp.OFPP_NONE
+ msg.command = ofp.OFPFC_ADD
+ msg.buffer_id = 0xffffffff
+ msg.match = match
+ if priority != 0 :
+ msg.priority = priority
+
+ act = action.action_output()
+ act.port = of_ports[1]
+ self.assertTrue(msg.actions.add(act), "could not add action")
+
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (pkt_MatchVlanId,match)
+
+def Match_Vlan_Pcp(self,of_ports,priority=0):
+ #Generate Match_Vlan_Id
+
+ #Create a simple tcp packet and generate match on ethernet dst address flow
+ pkt_MatchVlanPcp = simple_tcp_packet(dl_vlan_enable=True,dl_vlan=1,dl_vlan_pcp=10)
+ match = parse.packet_to_flow_match(pkt_MatchVlanPcp)
+ self.assertTrue(match is not None, "Could not generate flow match from pkt")
+
+ match.wildcards = ofp.OFPFW_ALL ^ofp.OFPFW_DL_VLAN_PCP
+ msg = message.flow_mod()
+ msg.out_port = ofp.OFPP_NONE
+ msg.command = ofp.OFPFC_ADD
+ msg.buffer_id = 0xffffffff
+ msg.match = match
+ if priority != 0 :
+ msg.priority = priority
+
+ act = action.action_output()
+ act.port = of_ports[1]
+ self.assertTrue(msg.actions.add(act), "could not add action")
+
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (pkt_MatchVlanPcp,match)
+
+
+def Match_Mul_L2(self,of_ports,priority=0):
+ #Generate Match_Mul_L2 flow
+
+ #Create a simple eth packet and generate match on ethernet protocol flow
+ pkt_MulL2 = simple_eth_packet(dl_type=0x88cc,dl_src='00:01:01:01:01:01',dl_dst='00:01:01:01:01:02')
+ match = parse.packet_to_flow_match(pkt_MulL2)
+ self.assertTrue(match is not None, "Could not generate flow match from pkt")
+
+ match.wildcards = ofp.OFPFW_ALL ^ofp.OFPFW_DL_TYPE ^ofp.OFPFW_DL_DST ^ofp.OFPFW_DL_SRC
+ msg = message.flow_mod()
+ msg.out_port = ofp.OFPP_NONE
+ msg.command = ofp.OFPFC_ADD
+ msg.buffer_id = 0xffffffff
+ msg.match = match
+ if priority != 0 :
+ msg.priority = priority
+
+ act = action.action_output()
+ act.port = of_ports[1]
+ self.assertTrue(msg.actions.add(act), "could not add action")
+
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (pkt_MulL2,match)
+
+
+def Match_Mul_L4(self,of_ports,priority=0):
+ #Generate Match_Mul_L4 flow
+
+ #Create a simple tcp packet and generate match on tcp protocol flow
+ pkt_MulL4 = simple_tcp_packet(tcp_sport=111,tcp_dport=112)
+ match = parse.packet_to_flow_match(pkt_MulL4)
+ self.assertTrue(match is not None, "Could not generate flow match from pkt")
+
+ match.wildcards = ofp.OFPFW_ALL ^ofp.OFPFW_TP_SRC ^ofp.OFPFW_TP_DST
+ msg = message.flow_mod()
+ msg.out_port = ofp.OFPP_NONE
+ msg.command = ofp.OFPFC_ADD
+ msg.buffer_id = 0xffffffff
+ msg.match = match
+ if priority != 0 :
+ msg.priority = priority
+
+ act = action.action_output()
+ act.port = of_ports[1]
+ self.assertTrue(msg.actions.add(act), "could not add action")
+
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (pkt_MulL4,match)
+
+def Match_Ip_Tos(self,of_ports,priority=0):
+ #Generate a Match on IP Type of service flow
+
+ #Create a simple tcp packet and generate match on Type of service
+ pkt_IpTos = simple_tcp_packet(ip_tos=3)
+ match = parse.packet_to_flow_match(pkt_IpTos)
+ self.assertTrue(match is not None, "Could not generate flow match from pkt")
+
+ match.wildcards = ofp.OFPFW_ALL ^ofp.OFPFW_NW_TOS
+ msg = message.flow_mod()
+ msg.out_port = ofp.OFPP_NONE
+ msg.command = ofp.OFPFC_ADD
+ msg.buffer_id = 0xffffffff
+ msg.match = match
+ if priority != 0 :
+ msg.priority = priority
+
+ act = action.action_output()
+ act.port = of_ports[1]
+ self.assertTrue(msg.actions.add(act), "could not add action")
+
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (pkt_IpTos,match)
+
+def Match_Tcp_Src(self,of_ports,priority=0):
+ #Generate Match_Tcp_Src
+
+ #Create a simple tcp packet and generate match on tcp source port flow
+ pkt_MatchTSrc = simple_tcp_packet(tcp_sport=111)
+ match = parse.packet_to_flow_match(pkt_MatchTSrc)
+ self.assertTrue(match is not None, "Could not generate flow match from pkt")
+
+ match.wildcards = ofp.OFPFW_ALL ^ofp.OFPFW_TP_SRC
+ msg = message.flow_mod()
+ msg.out_port = ofp.OFPP_NONE
+ msg.command = ofp.OFPFC_ADD
+ msg.buffer_id = 0xffffffff
+ msg.match = match
+ if priority != 0 :
+ msg.priority = priority
+
+ act = action.action_output()
+ act.port = of_ports[1]
+ self.assertTrue(msg.actions.add(act), "could not add action")
+
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (pkt_MatchTSrc,match)
+
+def Match_Tcp_Dst(self,of_ports,priority=0):
+ #Generate Match_Tcp_Dst
+
+ #Create a simple tcp packet and generate match on tcp destination port flow
+ pkt_MatchTDst = simple_tcp_packet(tcp_dport=112)
+ match = parse.packet_to_flow_match(pkt_MatchTDst)
+ self.assertTrue(match is not None, "Could not generate flow match from pkt")
+
+ match.wildcards = ofp.OFPFW_ALL ^ofp.OFPFW_TP_DST
+ msg = message.flow_mod()
+ msg.out_port = ofp.OFPP_NONE
+ msg.command = ofp.OFPFC_ADD
+ msg.buffer_id = 0xffffffff
+ msg.match = match
+ if priority != 0 :
+ msg.priority = priority
+
+ act = action.action_output()
+ act.port = of_ports[1]
+ self.assertTrue(msg.actions.add(act), "could not add action")
+
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (pkt_MatchTDst,match)
+
+
+
+
+
+def Match_Ethernet_Type(self,of_ports,priority=0):
+ #Generate a Match_Ethernet_Type flow
+
+ #Create a simple tcp packet and generate match on ethernet type flow
+ pkt_MatchType = simple_eth_packet(dl_type=0x88cc)
+ match = parse.packet_to_flow_match(pkt_MatchType)
+ self.assertTrue(match is not None, "Could not generate flow match from pkt")
+
+ match.wildcards = ofp.OFPFW_ALL ^ofp.OFPFW_DL_TYPE
+ msg = message.flow_mod()
+ msg.out_port = ofp.OFPP_NONE
+ msg.command = ofp.OFPFC_ADD
+ msg.buffer_id = 0xffffffff
+ msg.match = match
+ if priority != 0 :
+ msg.priority = priority
+
+ act = action.action_output()
+ act.port = of_ports[1]
+ self.assertTrue(msg.actions.add(act), "could not add action")
+
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (pkt_MatchType,match)
+
+
def Strict_Modify_Flow_Action(self,egress_port,match,priority=0):
# Strict Modify the flow Action
@@ -181,10 +488,49 @@
self.assertTrue(rv != -1, "Error installing flow mod")
self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+def Enqueue(self,ingress_port,egress_port,egress_queue_id):
+#Generate a flow with enqueue action i.e output to a queue configured on a egress_port
+
+ pkt = simple_tcp_packet()
+ match = packet_to_flow_match(self, pkt)
+ match.wildcards &= ~ofp.OFPFW_IN_PORT
+ self.assertTrue(match is not None,
+ "Could not generate flow match from pkt")
+
+ match.in_port = ingress_port
+ request = message.flow_mod()
+ request.match = match
+ request.buffer_id = 0xffffffff
+ act = action.action_enqueue()
+ act.port = egress_port
+ act.queue_id = egress_queue_id
+ self.assertTrue(request.actions.add(act), "Could not add action")
+
+ logging.info("Inserting flow")
+ rv = self.controller.message_send(request)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ return (pkt,match)
+
+
+
########################### Verify Stats Functions ###########################################################################################
-def Verify_TableStats(self,active_entries=0,):
+
+def Get_QueueStats(self,port_num,queue_id):
+#Generate Queue Stats request
+
+ request = message.queue_stats_request()
+ request.port_no = port_num
+ request.queue_id = queue_id
+ (queue_stats, p) = self.controller.transact(request)
+ self.assertNotEqual(queue_stats, None, "Queue stats request failed")
+
+ return (queue_stats,p)
+
+def Verify_TableStats(self,active_entries=0):
#Verify Table_Stats
#Send Table_Stats_Request
@@ -198,32 +544,46 @@
active_count += stat.active_count
self.assertTrue(active_entries == active_count,"Incorrect no. of flows in Table")
+def Verify_TableStats1(self,current_lookedup,current_matched,expect_lookup,expect_match):
+
+ stat_req = message.table_stats_request()
+ response, pkt = self.controller.transact(stat_req,
+ timeout=5)
+ self.assertTrue(response is not None,
+ "No response to stats request")
+ lookedup = 0
+ matched = 0
+
+ for obj in response.stats:
+ lookedup += obj.lookup_count
+ matched += obj.matched_count
+
+ lookedup_counter = lookedup-current_lookedup
+ matched_counter = matched-current_matched
+
+ self.assertTrue(lookedup_counter==expect_lookup, "lookup counter is not incremented properly")
+ self.assertTrue(matched_counter==expect_lookup, "matched counter is not incremented properly")
def Verify_FlowStats(self,match,byte_count=0,packet_count=0):
-# Verify flow counters : byte_count and packet_count
+ # Verify flow counters : byte_count and packet_count
stat_req = message.flow_stats_request()
stat_req.match = match
stat_req.table_id = 0xff
stat_req.out_port = ofp.OFPP_NONE
- test_timeout = 10
- all_packets_received = 0
- for i in range(0,test_timeout):
-
- response, pkt = self.controller.transact(stat_req,
- timeout=test_timeout)
- self.assertTrue(response is not None,
+ response, pkt = self.controller.transact(stat_req,
+ timeout=4)
+ self.assertTrue(response is not None,
"No response to stats request")
- for obj in response.stats:
- if ( obj.packet_count == packet_count and obj.byte_count == byte_count ) :
- all_packets_received = 1
+ packetcounter=0
+ bytecounter=0
+ for obj in response.stats:
+ packetcounter += obj.packet_count
+ bytecounter += obj.byte_count
- if all_packets_received:
- break
- sleep(1)
+ self.assertTrue(packetcounter==packet_count, "packet counter is not incremented properly")
+ self.assertTrue(bytecounter==byte_count, "byte counter is not incremented properly")
- self.assertTrue(all_packets_received,
- "Flow counters are incorrect")
def Verify_PortStats(self,in_port,rx_dropped):
#Verify Port counters like rx_dropped
@@ -234,7 +594,62 @@
self.assertTrue(resp is not None,"No response received for port stats request")
self.assertTrue(resp.rx_dropped == rx_dropped, "Packets not dropped")
+def Verify_PortStats1(self,out_port,current_counter,rx_packets):
+#Verify Port counters like rx_packets
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = out_port
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ rxpackets=0
+
+ for obj in response.stats:
+ rxpackets += obj.rx_packets
+ rx_packet_counter = rxpackets-current_counter
+ self.assertEqual(rx_packets,rx_packet_counter,"recieved packet counter is not incremented properly")
+
+def Verify_PortStats2(self,out_port,current_counter,tx_packets):
+#Verify Port counters like tx_packets
+
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = out_port
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ txpackets=0
+
+ for obj in response.stats:
+ txpackets += obj.tx_packets
+ tx_packet_counter = txpackets-current_counter
+ self.assertEqual(tx_packets,tx_packet_counter,"Transmitted packet counter is not incremented properly")
+
+
+def Verify_PortStats3(self,out_port,current_counter,rx_bytes):
+#Verify Port counters like rx_bytes
+
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = out_port
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ rxbytes=0
+
+ for obj in response.stats:
+ rxbytes += obj.rx_bytes
+ rx_byte_counter = rxbytes-current_counter
+ self.assertEqual(rx_bytes,rx_byte_counter,"Recieved byte counter is not incremented properly")
+
+def Verify_PortStats4(self,out_port,current_counter,tx_bytes):
+#Verify Port counters like tx_bytes
+
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = out_port
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ txbytes=0
+
+ for obj in response.stats:
+ txbytes += obj.tx_bytes
+ tx_byte_counter = txbytes-current_counter
+ self.assertEqual(tx_bytes,tx_byte_counter,"Transmitted byte counter is not incremented properly")
############################## Various delete commands #############################################################################################
@@ -307,3 +722,5 @@
cache_supported_actions = reply.actions
return cache_supported_actions
+##############################################################################################################################################################
+
diff --git a/tests/counters.py b/tests/counters.py
new file mode 100644
index 0000000..b14c4c6
--- /dev/null
+++ b/tests/counters.py
@@ -0,0 +1,779 @@
+"""These tests fall under Conformance Test-Suite (OF-SWITCH-1.0.0 TestCases).
+ Refer Documentation -- Detailed testing methodology
+ <Some of test-cases are directly taken from oftest> """
+
+"Test Suite 5 --> Counters"
+
+import logging
+
+import unittest
+import random
+
+from oftest import config
+import oftest.controller as controller
+import oftest.cstruct as ofp
+import oftest.message as message
+import oftest.dataplane as dataplane
+import oftest.action as action
+import oftest.parse as parse
+import oftest.base_tests as base_tests
+import time
+
+from oftest.testutils import *
+from time import sleep
+from FuncUtils import*
+
+
+def portQueuesGet(self, queue_stats, port_num):
+ result = []
+ for qs in queue_stats.stats:
+ if qs.port_no != port_num:
+ continue
+ result.append(qs.queue_id)
+ return result
+
+
+class FlowCounter1(base_tests.SimpleDataPlane):
+
+ """Verify Packet and Byte counters per flow are
+ incremented by no. of packets/bytes received for that flow"""
+
+ def runTest(self):
+
+ logging.info("Running Flow_Counter_1 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch state
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Insert any flow")
+ logging.info("Sending N Packets matching the flow")
+ logging.info("Verify packet/byte counters increment in accordance")
+
+ #Create a Match on Ingress flow
+ (pkt,match) = Wildcard_All_Except_Ingress(self,of_ports)
+
+ #Send Packets matching the flow
+ num_pkts = 5
+ byte_count = num_pkts*len(str(pkt))
+ for pkt_cnt in range(num_pkts):
+ self.dataplane.send(of_ports[0],str(pkt))
+
+ #Verify Recieved Packets/Bytes Per Flow
+ Verify_FlowStats(self,match,byte_count=byte_count,packet_count=num_pkts)
+
+
+class FlowCounter2(base_tests.SimpleDataPlane):
+
+ """Verify Duration_sec and Duration_nsec counters per flow varies in accordance with the amount of
+ time the flow was alive"""
+
+ def runTest(self):
+
+ logging.info("Running Flow_Counter_2 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch state
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Insert any flow")
+ logging.info("Send Flow_stats request after n sec intervals")
+ logging.info("Verify duration_sec and nsec counters are incrementing in accordance with the life of flow")
+
+ #Create a flow with match on ingress_port
+ pkt = simple_tcp_packet()
+ match = parse.packet_to_flow_match(pkt)
+ match.wildcards &= ~ofp.OFPFW_IN_PORT
+ self.assertTrue(match is not None,
+ "Could not generate flow match from pkt")
+ match.in_port = of_ports[0]
+ flow_mod_msg = message.flow_mod()
+ flow_mod_msg.match = match
+ flow_mod_msg.cookie = random.randint(0,9007199254740992)
+ flow_mod_msg.buffer_id = 0xffffffff
+ flow_mod_msg.idle_timeout = 0
+ flow_mod_msg.hard_timeout = 0
+ act = action.action_output()
+ act.port = of_ports[1]
+ self.assertTrue(flow_mod_msg.actions.add(act), "Could not add action")
+ rv = self.controller.message_send(flow_mod_msg)
+ self.assertTrue(rv != -1, "Error installing flow mod")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ #Create flow_stats request
+ test_timeout = 30
+ stat_req = message.flow_stats_request()
+ stat_req.match= match
+ stat_req.out_port = of_ports[1]
+
+ flow_stats_gen_ts = range (10,test_timeout,10)
+
+ for ts in range(0,test_timeout):
+ if ts in flow_stats_gen_ts:
+ response, pkt = self.controller.transact(stat_req)
+
+ self.assertTrue(response is not None,"No response to stats request")
+ self.assertTrue(len(response.stats) == 1,"Did not receive flow stats reply")
+
+ stat = response.stats[0]
+ self.assertTrue(stat.duration_sec == ts,"Flow stats reply incorrect")
+ logging.info("Duration of flow is " + str(stat.duration_sec) + str(stat.duration_nsec))
+
+ sleep(1)
+
+
+
+class PortCounter1(base_tests.SimpleDataPlane):
+
+ """Verify that rx_packets counter in the Port_Stats reply , increments when packets are received on a port"""
+
+ def runTest(self):
+
+ logging.info("Running Port_Counter_1 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ # Clear Switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Insert a flow with match on ingress_port")
+ logging.info("Send N Packets on an ingress_port P ")
+ logging.info("Send Port_Stats Request for Port P , verify recieved packets counters are incrementing in accordance")
+
+ #Insert a flow with match on all ingress port
+ (pkt, match ) = Wildcard_All_Except_Ingress(self,of_ports)
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.rx_packets
+
+ #Send packets matching the flow
+ num_pkts = 5
+ for pkt_cnt in range(num_pkts):
+ self.dataplane.send(of_ports[0],str(pkt))
+
+ #Verify recieved packet counters
+ Verify_PortStats1(self,of_ports[0],current_counter,num_pkts)
+
+
+class PortCounter2(base_tests.SimpleDataPlane):
+
+ """Verify that tx_packets counter in the Port_Stats reply , increments when packets are transmitted by a port"""
+
+ def runTest(self):
+
+ logging.info("Running Port_Counter_2 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch state
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+
+ logging.info("Insert any flow matching on in_port=ingress_port, action output to egress_port T ")
+ logging.info("Send N Packets matching the flow on ingress_port P ")
+ logging.info("Send Port_Stats Request for Port P , verify transmitted packets counters are incrementing in accordance")
+
+ #Insert a flow with match on all ingress port
+ (pkt, match ) = Wildcard_All_Except_Ingress(self,of_ports)
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.tx_packets
+
+ #Send packets matching the flow
+ num_pkts = 5
+ for pkt_cnt in range(num_pkts):
+ self.dataplane.send(of_ports[0],str(pkt))
+
+ #Verify transmitted_packet counters
+ Verify_PortStats2(self,of_ports[0],current_counter,num_pkts)
+
+
+class PortCounter3(base_tests.SimpleDataPlane):
+
+ """Verify that recieved bytes counter in the Port_Stats reply , increments in accordance with the bytes recieved on a port"""
+
+ def runTest(self):
+
+ logging.info("Running Port_Counter_3 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Insert any flow matching on in_port=ingress_port")
+ logging.info("Send N Packets matching the flow on ingress_port P ")
+ logging.info("Send Port_Stats Request for Port P , verify recieved bytes counters are incrementing in accordance")
+
+ #Insert a flow with match on all ingress port
+ (pkt, match ) = Wildcard_All_Except_Ingress(self,of_ports)
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.rx_bytes
+
+ #Send packets matching the flow.
+ num_pkts = 5
+ byte_count = num_pkts*len(str(pkt))
+ for pkt_cnt in range(num_pkts):
+ self.dataplane.send(of_ports[0],str(pkt))
+
+
+ #Verify recieved_bytes counters
+ Verify_PortStats3(self,of_ports[0],current_counter,byte_count)
+
+
+class PortCounter4(base_tests.SimpleDataPlane):
+
+ """Verify that trasnsmitted bytes counter in the Port_Stats reply , increments in accordance with the bytes trasmitted by a port"""
+
+ def runTest(self):
+
+ logging.info("Running Port_Counter_4 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Insert any flow matching on in_port=ingress_port,action = output to egress_port")
+ logging.info("Send N Packets matching the flow on ingress_port P ")
+ logging.info("Send Port_Stats Request for Port P , verify trasmitted bytes counters are incrementing in accordance")
+
+ #Insert a flow with match on all ingress port
+ (pkt, match ) = Wildcard_All_Except_Ingress(self,of_ports)
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.tx_bytes
+
+ #Send packets matching the flow.
+ num_pkts = 5
+ byte_count = num_pkts*len(str(pkt))
+ for pkt_cnt in range(num_pkts):
+ self.dataplane.send(of_ports[0],str(pkt))
+
+
+ #Verify trasmitted_bytes counters
+ Verify_PortStats4(self,of_ports[0],current_counter,byte_count)
+
+
+class TableCounter1(base_tests.SimpleDataPlane):
+
+ """Verify that active_count counter in the Table_Stats reply , increments in accordance with the flows inserted in a table"""
+
+ def runTest(self):
+
+ logging.info("Running Table_Counter_1 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch state
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Insert any flow matching on in_port=ingress_port,action = output to egress_port")
+ logging.info("Send Table_Stats, verify active_count counter is incremented in accordance")
+
+ #Insert a flow with match on all ingress port
+ (pkt, match ) = Wildcard_All_Except_Ingress(self,of_ports)
+
+ #Generate Table_Stats
+ Verify_TableStats(self,active_entries=1)
+
+
+class TableCounter2(base_tests.SimpleDataPlane):
+
+ """Verify that lookup_count and matched_count counter in the Table_Stats reply
+ increments in accordance with the packets looked up and matched with the flows in the table"""
+
+ def runTest(self):
+
+ logging.info("Running Table_Counter_1 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch state
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Insert any flow matching on in_port=ingress_port,action = output to egress_port")
+ logging.info("Send N packets matching the flow, N' packets not matching the flow")
+ logging.info("Send Table_Stats, verify lookup_count = N+N' & matched_count=N ")
+
+ # Send Table_Stats reuqest (retrieve current table counters )
+
+ stat_req = message.table_stats_request()
+ response, pkt = self.controller.transact(stat_req,
+ timeout=5)
+ self.assertTrue(response is not None,
+ "No response to stats request")
+ current_lookedup = 0
+ current_matched = 0
+
+ for obj in response.stats:
+ current_lookedup += obj.lookup_count
+ current_matched += obj.matched_count
+
+ #Insert a flow with match on all ingress port
+ (pkt, match ) = Wildcard_All_Except_Ingress(self,of_ports)
+
+ #send packet pkt N times (pkt matches the flow)
+ num_sends = 5
+ for pkt_cnt in range(num_sends):
+ self.dataplane.send(of_ports[0],str(pkt))
+
+ #send packet pkt N' (pkt does not match the flow)
+ num_sends2 = 5
+ for pkt_cnt in range(num_sends):
+ self.dataplane.send(of_ports[1],str(pkt))
+
+ #Verify lookup_count and matched_count counters.
+ Verify_TableStats1(self,current_lookedup,current_matched,num_sends+num_sends2,num_sends)
+
+
+
+class QueueCounter1(base_tests.SimpleDataPlane):
+
+ """Verify that tx_packets in the queue_stats reply increments in accordance with the number of transmitted packets"""
+
+ def runTest(self):
+ logging.info("Running Queue_Counter_1 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ # Get queue stats from switch (retrieve current state)
+ (queue_stats,p) = Get_QueueStats(self,ofp.OFPP_ALL,ofp.OFPQ_ALL)
+
+ for idx in range(len(of_ports)):
+ ingress_port = of_ports[idx]
+ egress_port = of_ports[(idx + 1) % len(of_ports)]
+
+ queue_id = portQueuesGet(self,queue_stats,egress_port)
+
+ for egress_queue_id in queue_id:
+
+ #Clear switch state
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ # Get Queue stats for selected egress queue only
+ (qs_before,p) = Get_QueueStats(self,egress_port,egress_queue_id)
+
+ #Insert a flow with enqueue action to queues configured on egress_port
+ (pkt,match) = Enqueue(self,ingress_port,egress_port,egress_queue_id)
+
+ #Send packet on the ingress_port and verify its received on egress_port
+ SendPacket(self,pkt,ingress_port,egress_port)
+
+ # FIXME: instead of sleeping, keep requesting queue stats until
+ # the expected queue counter increases or some large timeout is
+ # reached
+ time.sleep(2)
+
+ # Get Queue Stats for selected egress queue after packets have been sent
+ (qs_after,p) = Get_QueueStats(self,egress_port,egress_queue_id)
+
+ #Verify transmitted packets counter is incremented in accordance
+ self.assertEqual(qs_after.stats[0].tx_packets,qs_before.stats[0].tx_packets + 1,"tx_packet count incorrect")
+
+
+class QueueCounter2(base_tests.SimpleDataPlane):
+
+ """Verify that tx_bytes in the queue_stats reply increments in accordance with the number of transmitted bytes"""
+
+ def runTest(self):
+ logging.info("Running Queue_Counter_2 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ # Get queue stats from switch (retrieve current state)
+ (queue_stats,p) = Get_QueueStats(self,ofp.OFPP_ALL,ofp.OFPQ_ALL)
+
+ for idx in range(len(of_ports)):
+ ingress_port = of_ports[idx]
+ egress_port = of_ports[(idx + 1) % len(of_ports)]
+
+ queue_id = portQueuesGet(self,queue_stats,egress_port)
+
+ for egress_queue_id in queue_id:
+
+ #Clear switch state
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ # Get Queue stats for selected egress queue only
+ (qs_before,p) = Get_QueueStats(self,egress_port,egress_queue_id)
+
+ #Insert a flow with enqueue action to queues configured on egress_port
+ (pkt,match) = Enqueue(self,ingress_port,egress_port,egress_queue_id)
+
+ #Send packet on the ingress_port and verify its received on egress_port
+ SendPacket(self,pkt,ingress_port,egress_port)
+
+ # FIXME: instead of sleeping, keep requesting queue stats until
+ # the expected queue counter increases or some large timeout is
+ # reached
+ time.sleep(2)
+
+ # Get Queue Stats for selected egress queue after packets have been sent
+ (qs_after,p) = Get_QueueStats(self,egress_port,egress_queue_id)
+
+ #Verify transmitted packets counter is incremented in accordance
+ self.assertEqual(qs_after.stats[0].tx_bytes,qs_before.stats[0].tx_bytes + 1,"tx_bytes count incorrect")
+
+
+
+class RxDrops(base_tests.SimpleDataPlane):
+
+ """Verify that rx_dropped counters in the Port_Stats reply increments in accordance with the packets dropped by RX"""
+
+ def runTest(self):
+
+ logging.info("Running Rx_Drops test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Send Port_Stats Request")
+ logging.info("Verify reply has rx_dropped count ")
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.rx_dropped
+
+ logging.info("recieved dropped count is :" + str(current_counter))
+
+
+
+class TxDrops(base_tests.SimpleDataPlane):
+
+ """Verify that tx_dropped counters in the Port_Stats reply increments in accordance with the packets dropped by TX"""
+
+ def runTest(self):
+
+ logging.info("Running Tx_Drops test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Send Port_Stats Request")
+ logging.info("Verify reply has tx_dropped count ")
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.tx_dropped
+
+ logging.info("Transmitted dropped count is :" + str(current_counter))
+
+
+class RxErrors(base_tests.SimpleDataPlane):
+
+ """Verify that rx_errors counters in the Port_Stats reply increments in accordance with number of recieved error
+ This is a super-set of more specific receive errors and should be greater than or equal to the sum of all
+ rx_*_err values"""
+
+ def runTest(self):
+
+ logging.info("Running Rx_Errors test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Send Port_Stats Request")
+ logging.info("Verify reply has rx_errors count ")
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.rx_errors
+
+ logging.info("Recieve Errors count is :" + str(current_counter))
+
+
+class TxErrors(base_tests.SimpleDataPlane):
+
+ """Verify that Tx_errors counters in the Port_Stats reply increments in accordance with number of trasmit error"""
+
+ def runTest(self):
+
+ logging.info("Running Tx_Errors test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Send Port_Stats Request")
+ logging.info("Verify reply has Tx_errors count ")
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.tx_errors
+
+ logging.info("Trasmit Error count is :" + str(current_counter))
+
+
+class RxFrameErr(base_tests.SimpleDataPlane):
+
+ """Verify that rx_frm_err counters in the Port_Stats reply increments in accordance with the number of frame alignment errors"""
+
+ def runTest(self):
+
+ logging.info("Running Rx_Frame_Err test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Send Port_Stats Request")
+ logging.info("Verify reply has rx_frame_err count ")
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.rx_frame_err
+
+ logging.info("Recieve Frame Errors count is :" + str(current_counter))
+
+
+
+
+
+class RxOErr(base_tests.SimpleDataPlane):
+
+ """Verify that rx_over_err counters in the Port_Stats reply increments in accordance with the number of with RX overrun"""
+
+ def runTest(self):
+
+ logging.info("Running Rx_O_Err test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Send Port_Stats Request")
+ logging.info("Verify reply has rx_over_err count ")
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.rx_over_err
+
+ logging.info("Recieve Overrun Errors count is :" + str(current_counter))
+
+
+
+
+class RxCrcErr(base_tests.SimpleDataPlane):
+
+ """Verify that rx_crc_err counters in the Port_Stats reply increments in accordance with the number of crc errors"""
+
+ def runTest(self):
+
+ logging.info("Running Port_Counter_9 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Send Port_Stats Request")
+ logging.info("Verify reply has rx_crc_err count ")
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.rx_crc_err
+
+ logging.info("Recieve CRC Errors count is :" + str(current_counter))
+
+
+
+class Collisions(base_tests.SimpleDataPlane):
+
+ """Verify that collisons counters in the Port_Stats reply increments in accordance with the collisions encountered by the switch """
+
+ def runTest(self):
+
+ logging.info("Running Collisions test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Send Port_Stats Request")
+ logging.info("Verify reply has Collisions count ")
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.collisions
+
+ logging.info("collisions count is :" + str(current_counter))
+
+
+
+
+class QueueCounter3(base_tests.SimpleDataPlane):
+
+ """Verify that tx_errors in the queue_stats reply increments in accordance with the number of packets dropped due to overrun """
+
+ def runTest(self):
+
+ logging.info("Running Queue_Counter_3 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Send Queue_Stats Request")
+ logging.info("Verify reply has Tramitted Overrun errors count ")
+
+ # Send Port_Stats request for the ingress port (retrieve current counter state)
+ port_stats_req = message.port_stats_request()
+ port_stats_req.port_no = of_ports[0]
+ response,pkt = self.controller.transact(port_stats_req)
+ self.assertTrue(response is not None,"No response received for port stats request")
+ current_counter=0
+
+ for obj in response.stats:
+ current_counter += obj.tx_errors
+
+ logging.info("Transmit Overrun Error count is :" + str(current_counter))
+
+