# Buggy code
def valve_flowreorder(input_ofmsgs, use_barriers=True):
    """Reorder flows for better OFA performance."""
    # Move all deletes to be first, and add one barrier,
    # while optionally randomizing order. Platforms that do
    # parallel delete will perform better and platforms that
    # don't will have at most only one barrier to deal with.
    output_ofmsgs = []
    by_kind = _partition_ofmsgs(input_ofmsgs)

    # Suppress all other deletes if a global delete is present.
    delete_global_ofmsgs = by_kind.get("deleteglobal", [])
    if delete_global_ofmsgs:
        by_kind["delete"] = []

    for kind, random_order, suggest_barrier in _OFMSG_ORDER:
        ofmsgs = dedupe_ofmsgs(by_kind.get(kind, []), random_order)
        if ofmsgs:
            output_ofmsgs.extend(ofmsgs)
            if use_barriers and suggest_barrier:
                output_ofmsgs.append(barrier())
    return output_ofmsgs


# Traceback (AssertionError)
port order: -o 2,3,0,1
Using config from /etc/faucet/hw_switch_config.yaml
Testing hardware, forcing test serialization
Logging test results in /var/tmp/faucet-tests-sakye6bn
test ports server started
adding test FaucetNailedFailoverForwardingOrderedTest
adding test FaucetNailedFailoverForwardingTest

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK
running 0 tests in parallel and 2 tests serial
test_untagged (mininet_tests.FaucetNailedFailoverForwardingOrderedTest) ... *** Error setting resource limits. Mininet's performance may be affected.
ok
test_untagged (mininet_tests.FaucetNailedFailoverForwardingTest) ... FAIL

======================================================================
FAIL: test_untagged (mininet_tests.FaucetNailedFailoverForwardingTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/faucet-src/clib/mininet_test_base.py", line 481, in tearDown
self.assertFalse(oferrors, msg=oferrors)
AssertionError: "Mar 17 22:12:31 faucet.valve ERROR    DPID 222613276036429 (0xca77313d8d4d) faucet-1 OFError type: OFPET_GROUP_MOD_FAILED code: OFPGMFC_GROUP_EXISTS version=0x4,msg_type=0x1,msg_len=0x5c,xid=0xc369eeb2,OFPErrorMsg(code=0,data=bytearray(b'\\x04\\x0f\\x00P\\xc3i\\xee\\xb2\\x00\\x00\\x03\\x00\\x00\\x00\\x03\\xe9\\x00 \\x00\\x00\\x00\\x00\\x00\\x05\\xff\\xff\\xff\\xff\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x10\\x00\\x00\\x00\\x05\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00 \\x00\\x00\\x00\\x00\\x00\\x02\\xff\\xff\\xff\\xff\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x10\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'),type=6) caused by version=0x4,msg_type=0xf,msg_len=0x50,xid=0xc369eeb2,OFPGroupMod(buckets=[OFPBucket(actions=[OFPActionOutput(len=16,max_len=0,port=5,type=0)],len=32,watch_group=4294967295,watch_port=5,weight=0), OFPBucket(actions=[OFPActionOutput(len=16,max_len=0,port=2,type=0)],len=32,watch_group=4294967295,watch_port=2,weight=0)],command=0,group_id=1001,type=3)\n\n\nMar 17 22:12:31 faucet.valve ERROR    DPID 222613276036429 (0xca77313d8d4d) faucet-1 OFError type: OFPET_GROUP_MOD_FAILED code: OFPGMFC_GROUP_EXISTS version=0x4,msg_type=0x1,msg_len=0x5c,xid=0xc369eeb3,OFPErrorMsg(code=0,data=bytearray(b'\\x04\\x0f\\x00P\\xc3i\\xee\\xb3\\x00\\x00\\x03\\x00\\x00\\x00\\x03\\xea\\x00 \\x00\\x00\\x00\\x00\\x00\\x05\\xff\\xff\\xff\\xff\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x10\\x00\\x00\\x00\\x05\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00 \\x00\\x00\\x00\\x00\\x00\\x02\\xff\\xff\\xff\\xff\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x10\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'),type=6) caused by version=0x4,msg_type=0xf,msg_len=0x50,xid=0xc369eeb3,OFPGroupMod(buckets=[OFPBucket(actions=[OFPActionOutput(len=16,max_len=0,port=5,type=0)],len=32,watch_group=4294967295,watch_port=5,weight=0), OFPBucket(actions=[OFPActionOutput(len=16,max_len=0,port=2,type=0)],len=32,watch_group=4294967295,watch_port=2,weight=0)],command=0,group_id=1002,type=3)\n" is not false : Mar 17 22:12:31 faucet.valve ERROR    DPID 222613276036429 (0xca77313d8d4d) faucet-1 OFError type: OFPET_GROUP_MOD_FAILED code: OFPGMFC_GROUP_EXISTS version=0x4,msg_type=0x1,msg_len=0x5c,xid=0xc369eeb2,OFPErrorMsg(code=0,data=bytearray(b'\x04\x0f\x00P\xc3i\xee\xb2\x00\x00\x03\x00\x00\x00\x03\xe9\x00 \x00\x00\x00\x00\x00\x05\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x02\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00'),type=6) caused by version=0x4,msg_type=0xf,msg_len=0x50,xid=0xc369eeb2,OFPGroupMod(buckets=[OFPBucket(actions=[OFPActionOutput(len=16,max_len=0,port=5,type=0)],len=32,watch_group=4294967295,watch_port=5,weight=0), OFPBucket(actions=[OFPActionOutput(len=16,max_len=0,port=2,type=0)],len=32,watch_group=4294967295,watch_port=2,weight=0)],command=0,group_id=1001,type=3)


Mar 17 22:12:31 faucet.valve ERROR    DPID 222613276036429 (0xca77313d8d4d) faucet-1 OFError type: OFPET_GROUP_MOD_FAILED code: OFPGMFC_GROUP_EXISTS version=0x4,msg_type=0x1,msg_len=0x5c,xid=0xc369eeb3,OFPErrorMsg(code=0,data=bytearray(b'\x04\x0f\x00P\xc3i\xee\xb3\x00\x00\x03\x00\x00\x00\x03\xea\x00 \x00\x00\x00\x00\x00\x05\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x02\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00'),type=6) caused by version=0x4,msg_type=0xf,msg_len=0x50,xid=0xc369eeb3,OFPGroupMod(buckets=[OFPBucket(actions=[OFPActionOutput(len=16,max_len=0,port=5,type=0)],len=32,watch_group=4294967295,watch_port=5,weight=0), OFPBucket(actions=[OFPActionOutput(len=16,max_len=0,port=2,type=0)],len=32,watch_group=4294967295,watch_port=2,weight=0)],command=0,group_id=1002,type=3)


----------------------------------------------------------------------
Ran 2 tests in 80.138s

# Fixed code
def valve_flowreorder(input_ofmsgs, use_barriers=True):
    """Reorder flows for better OFA performance."""
    # Move all deletes to be first, and add one barrier,
    # while optionally randomizing order. Platforms that do
    # parallel delete will perform better and platforms that
    # don't will have at most only one barrier to deal with.
    output_ofmsgs = []
    by_kind = _partition_ofmsgs(input_ofmsgs)

    # Suppress all other relevant deletes if a global delete is present.
    delete_global_ofmsgs = by_kind.get("deleteglobal", [])
    if delete_global_ofmsgs:
        global_types = []
        for ofmsg in delete_global_ofmsgs:
            global_types.append(type(ofmsg))
        new_delete = []
        for ofmsg in by_kind.get("delete", []):
            if type(ofmsg) not in global_types:
                new_delete.append(ofmsg)
        by_kind["delete"] = new_delete

    for kind, random_order, suggest_barrier in _OFMSG_ORDER:
        ofmsgs = dedupe_ofmsgs(by_kind.get(kind, []), random_order)
        if ofmsgs:
            output_ofmsgs.extend(ofmsgs)
            if use_barriers and suggest_barrier:
                output_ofmsgs.append(barrier())
    return output_ofmsgs