Merge into master from pull request #122:
flow overwrite testcase (https://github.com/floodlight/oftest/pull/122)
diff --git a/src/python/oftest/testutils.py b/src/python/oftest/testutils.py
index 104d3b5..f2d4b3d 100644
--- a/src/python/oftest/testutils.py
+++ b/src/python/oftest/testutils.py
@@ -1377,7 +1377,6 @@
return get_stats(test, req)
def verify_flow_stats(test, match, table_id=0xff,
- out_port=None,
initial=[],
pkts=None, bytes=None):
"""
@@ -1387,8 +1386,6 @@
get_flow_stats(). If 'initial' is not given the counters are assumed to
begin at 0.
"""
- if out_port == None:
- out_port = ofp.OFPP_NONE
def accumulate(stats):
pkts_acc = bytes_acc = 0
@@ -1402,7 +1399,7 @@
# Wait 10s for counters to update
pkt_diff = byte_diff = None
for i in range(0, 100):
- stats = get_flow_stats(test, match, table_id=table_id, out_port=out_port)
+ stats = get_flow_stats(test, match, table_id=table_id)
pkts_after, bytes_after = accumulate(stats)
pkt_diff = pkts_after - pkts_before
byte_diff = bytes_after - bytes_before
diff --git a/tests-1.3/flow_mod.py b/tests-1.3/flow_mod.py
new file mode 100644
index 0000000..2f0e711
--- /dev/null
+++ b/tests-1.3/flow_mod.py
@@ -0,0 +1,88 @@
+# Distributed under the OpenFlow Software License (see LICENSE)
+# Copyright (c) 2014 Big Switch Networks, Inc.
+"""
+Flow-mod test cases
+"""
+
+import logging
+
+import oftest
+from oftest import config
+import oftest.base_tests as base_tests
+import ofp
+from loxi.pp import pp
+
+from oftest.testutils import *
+from oftest.parse import parse_ipv6
+
+class Overwrite(base_tests.SimpleDataPlane):
+ """
+ Verify that overwriting a flow changes most fields but preserves stats
+ """
+ def runTest(self):
+ in_port, out_port1, out_port2 = openflow_ports(3)
+
+ delete_all_flows(self.controller)
+
+ table_id = test_param_get("table", 0)
+ match = ofp.match([
+ ofp.oxm.in_port(in_port),
+ ])
+ priority = 1000
+
+ logging.info("Inserting flow")
+ request = ofp.message.flow_add(
+ table_id=table_id,
+ match=match,
+ instructions=[
+ ofp.instruction.apply_actions([ofp.action.output(out_port1)]),
+ ],
+ buffer_id=ofp.OFP_NO_BUFFER,
+ priority=priority,
+ flags=ofp.OFPFF_SEND_FLOW_REM,
+ cookie=0x1234,
+ hard_timeout=1000,
+ idle_timeout=2000)
+ self.controller.message_send(request)
+ do_barrier(self.controller)
+
+ # Send a packet through so that we can check stats were preserved
+ self.dataplane.send(in_port, str(simple_tcp_packet(pktlen=100)))
+ verify_flow_stats(self, ofp.match(), table_id=table_id, pkts=1)
+
+ # Send a flow-add with the same table_id, match, and priority, causing
+ # an overwrite
+ logging.info("Overwriting flow")
+ request = ofp.message.flow_add(
+ table_id=table_id,
+ match=match,
+ instructions=[
+ ofp.instruction.apply_actions([ofp.action.output(out_port2)]),
+ ],
+ buffer_id=ofp.OFP_NO_BUFFER,
+ priority=priority,
+ flags=0,
+ cookie=0xabcd,
+ hard_timeout=3000,
+ idle_timeout=4000)
+ self.controller.message_send(request)
+ do_barrier(self.controller)
+
+ # Should not get a flow-removed message
+ msg, _ = self.controller.poll(exp_msg=ofp.message.flow_removed,
+ timeout=oftest.ofutils.default_negative_timeout)
+ self.assertEquals(msg, None)
+
+ # Check that the fields in the flow stats entry match the second flow-add
+ stats = get_flow_stats(self, ofp.match())
+ self.assertEquals(len(stats), 1)
+ entry = stats[0]
+ logging.debug(entry.show())
+ self.assertEquals(entry.instructions, request.instructions)
+ self.assertEquals(entry.flags, request.flags)
+ self.assertEquals(entry.cookie, request.cookie)
+ self.assertEquals(entry.hard_timeout, request.hard_timeout)
+ self.assertEquals(entry.idle_timeout, request.idle_timeout)
+
+ # Flow stats should have been preserved
+ verify_flow_stats(self, ofp.match(), table_id=table_id, pkts=1)