Changes to group tests to get them to work on OVS.

Use barriers instead of sleeps, test multicast forwarding out 2 ONU ports, etc.
diff --git a/olt-topo.py b/olt-topo.py
index 438a59f..581084c 100755
--- a/olt-topo.py
+++ b/olt-topo.py
@@ -23,7 +23,7 @@
 
 if __name__ == '__main__':
     setLogLevel('debug')
-    topo = OltTopo()
+    topo = OltTopo(k=2)
 
     net = Mininet( topo=topo, controller=RemoteController )
 
diff --git a/olt.py b/olt.py
index b2ea421..5b15771 100644
--- a/olt.py
+++ b/olt.py
@@ -12,6 +12,7 @@
 from oftest.testutils import *
 
 onu_port = test_param_get("onu_port", 1)
+onu_port2 = test_param_get("onu_port2", 2)
 olt_port = test_param_get("olt_port", 129)
 
 def testPacketIn(self, match, parsed_pkt):
@@ -36,7 +37,7 @@
     logging.info("Inserting flow sending matching packets to controller")
     self.controller.message_send(request)
     do_barrier(self.controller)
-	
+        
     for of_port in config["port_map"]:
         logging.info("PacketInExact test, port %d", of_port)
         self.dataplane.send(of_port, pkt)
@@ -125,7 +126,7 @@
 
         verify_no_errors(self.controller)
 
-	vlan_id = 201
+        vlan_id = 201
         match = ofp.match()
         match.oxm_list.append(ofp.oxm.in_port(onu_port))
         match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id ))
@@ -136,8 +137,8 @@
             match=match,
             instructions=[
                 ofp.instruction.apply_actions(
-                    actions=[
-                        ofp.action.output(port=olt_port)]),
+                    actions=[ofp.action.output(port=olt_port)]
+                ),
                 ofp.instruction.meter(meter_id = 1)    
                 ],
             buffer_id=ofp.OFP_NO_BUFFER,
@@ -157,9 +158,9 @@
             match=match,
             instructions=[
                 ofp.instruction.apply_actions(
-                    actions=[
-                        ofp.action.output(port=onu_port)]),
-                    ofp.instruction.meter(meter_id = 1)    
+                    actions=[ofp.action.output(port=onu_port)]
+                ),
+                ofp.instruction.meter(meter_id = 1)    
                 ],
             buffer_id=ofp.OFP_NO_BUFFER,
             priority=1000)
@@ -170,15 +171,15 @@
         do_barrier(self.controller)
         time.sleep(5)
         
-	inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=vlan_id, vlan_pcp=0)
-	# downstream
+        inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=vlan_id, vlan_pcp=0)
+        # downstream
         self.dataplane.send(olt_port, str(inPkt))
         verify_packet(self, inPkt, onu_port)
         # upstream
         self.dataplane.send(olt_port, str(inPkt))
         verify_packet(self, inPkt, onu_port)
 
-	# clean up the test
+        # clean up the test
         meter_mod = ofp.message.meter_mod(xid = 2, command = ofp.OFPMC_DELETE, meter_id = 1)
         self.controller.message_send(meter_mod)
         time.sleep(1)
@@ -249,9 +250,9 @@
             match=match,
             instructions=[
                 ofp.instruction.apply_actions(
-       		    actions=[
-			ofp.action.pop_vlan(),
-			ofp.action.output(port=1)])], 
+                    actions=[
+                        ofp.action.pop_vlan(),
+                        ofp.action.output(port=1)])], 
             buffer_id=ofp.OFP_NO_BUFFER,
             priority=1000)
 
@@ -283,41 +284,63 @@
         # Send tagged packet in the ONU port and expect no packets to come out
         self.dataplane.send(onu_port, str(inPkt))
         verify_packets(self, outPkt, [])
-        
+
+def createAllGroupAdd(group_id, ports=[]):
+    buckets = []
+    
+    for portNum in ports:
+        buckets.append(ofp.common.bucket(watch_port=ofp.OFPP_ANY, watch_group=ofp.OFPG_ANY,
+                                         actions=[ofp.action.output(port=portNum)]))
+    
+    group_add = ofp.message.group_add(group_type = ofp.OFPGT_ALL, group_id=group_id, buckets=buckets)
+    
+    return group_add
+
+def createAllGroupMod(group_id, ports=[]):
+    buckets = []
+    
+    for portNum in ports:
+        buckets.append(ofp.common.bucket(watch_port=ofp.OFPP_ANY, watch_group=ofp.OFPG_ANY,
+                                         actions=[ofp.action.output(port=portNum)]))
+    
+    group_mod = ofp.message.group_mod(command=ofp.OFPGC_MODIFY, group_type = ofp.OFPGT_ALL, group_id=group_id, buckets=buckets)
+    
+    return group_mod
+    
+
 class TestGroupAdd(base_tests.SimpleDataPlane):
        
     def runTest(self):
         logging.info("Running Group tests")
         delete_all_flows(self.controller)
+        delete_all_groups(self.controller)
 
-	test_group_id = 1 
-	onu_port1 = 130
-	onu_port2 = 131
-	# output to two ONU
-	bucket = ofp.common.bucket(actions=[ofp.action.output(port=onu_port1), ofp.action.output(port=onu_port2)]) 
-        group_add = ofp.message.group_add(xid = 1, group_type = ofp.OFPGT_ALL, group_id = test_group_id, buckets = [ bucket ])
+        test_group_id = 1 
+
+        # output to two ONU
+        group_add = createAllGroupAdd(test_group_id, ports=[onu_port, onu_port2])
 
         self.controller.message_send(group_add)
-        time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
         # Remove the group and then readd it.
-        group_delete = ofp.message.group_delete(xid = 2, group_id = test_group_id)
+        group_delete = ofp.message.group_delete(group_id = test_group_id)
         self.controller.message_send(group_delete)
-	time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
-	group_add = ofp.message.group_add(xid = 1, group_type = ofp.OFPGT_ALL, group_id = test_group_id, buckets = [ bucket ])
+        group_add = createAllGroupAdd(test_group_id, [onu_port, onu_port2])
         self.controller.message_send(group_add)
-        time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
 
-	# clean up the test
-        group_delete = ofp.message.group_delete(xid = 2, group_id = test_group_id)
+        # clean up the test
+        group_delete = ofp.message.group_delete(group_id = test_group_id)
         self.controller.message_send(group_delete)
         
-	time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
         
 class TestGroupMod(base_tests.SimpleDataPlane):
@@ -325,54 +348,50 @@
     def runTest(self):
         logging.info("Running Group tests")
         delete_all_flows(self.controller)
+        delete_all_groups(self.controller)
 
-	test_group_id = 1 
-	onu_port1 = 130
-	onu_port2 = 131
-	bucket = ofp.common.bucket(actions=[ofp.action.output(port=onu_port1)]) 
-        group_add = ofp.message.group_add(xid = 1, group_type = ofp.OFPGT_ALL, group_id = test_group_id, buckets = [ bucket ])
+        test_group_id = 1 
+
+        group_add = createAllGroupAdd(test_group_id, [onu_port, onu_port2])
 
         self.controller.message_send(group_add)
-        time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
-	
-	# Modifying the group
-	bucket = ofp.common.bucket(actions=[ofp.action.output(port=onu_port2)]) 
-	group_mod = ofp.message.group_mod(xid = 2, command = 1, group_type = ofp.OFPGT_ALL, group_id = test_group_id, buckets = [ bucket ])
-
-	self.controller.message_send(group_mod)
-        time.sleep(1)
+        
+        # Modifying the group
+        group_mod = createAllGroupMod(test_group_id, [onu_port2])
+        
+        self.controller.message_send(group_mod)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
-	# Add a bucket into the group
-	bucket2 = ofp.common.bucket(actions=[ofp.action.output(port=onu_port1)]) 
-	group_mod = ofp.message.group_mod(xid = 2, command = 1, group_type = ofp.OFPGT_ALL, group_id = test_group_id, buckets = [ bucket, bucket2 ])
-	self.controller.message_send(group_mod)
-        time.sleep(1)
+        # Add a bucket into the group
+        group_mod = createAllGroupMod(test_group_id, [onu_port, onu_port2])
+        self.controller.message_send(group_mod)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
         # Modifying a non-existing group
-	bucket = ofp.common.bucket(actions=[ofp.action.output(port=onu_port2)]) 
-	group_mod = ofp.message.group_mod(xid = 3, command = 1, group_type = ofp.OFPGT_ALL, group_id = 777, buckets = [ bucket ])
+        group_mod = createAllGroupMod(777, [onu_port2])
 
-	self.controller.message_send(group_mod)
-        time.sleep(10)
-	errorExperienced = 0
+        self.controller.message_send(group_mod)
+        do_barrier(self.controller)
+        errorExperienced = 0
         try:
             verify_no_errors(self.controller)
         except AssertionError as e:
-	    errorExperienced = 1
+            errorExperienced = 1
             if (not (e.message == "unexpected error type=6 code=8")):
-               raise AssertionError("Incorrect error type: %s" % e.message)
-	if not errorExperienced: 
-           raise AssertionError("An error message is expected, but not shown.")
-	  
+                raise AssertionError("Incorrect error type: %s" % e.message)
+        if not errorExperienced: 
+            raise AssertionError("An error message is expected, but not shown.")
+          
  
-	# clean up the test
+        # clean up the test
         group_delete = ofp.message.group_delete(xid = 2, group_id = test_group_id)
         self.controller.message_send(group_delete)
         
-	time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
 class TestDuplicateGroup(base_tests.SimpleDataPlane):
@@ -380,35 +399,34 @@
     def runTest(self):
         logging.info("Running Group tests")
         delete_all_flows(self.controller)
+        delete_all_groups(self.controller)
 
-	test_group_id = 1 
-	bucket = ofp.common.bucket(actions=[ofp.action.output(port=onu_port)]) 
-        group_add = ofp.message.group_add(xid = 1, group_type = ofp.OFPGT_ALL, group_id = test_group_id, buckets = [ bucket ])
+        test_group_id = 1 
+        group_add = createAllGroupAdd(test_group_id, ports=[onu_port])
 
         self.controller.message_send(group_add)
-        time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
-	
-	# Add the same group id
+        
+        # Add the same group id
         duplicate_group_fail = 0 
-        group_add = ofp.message.group_add(xid = 1, group_type = ofp.OFPGT_ALL, group_id = test_group_id, buckets = [ bucket ])
-	
+        
         self.controller.message_send(group_add)
-        time.sleep(1)
+        do_barrier(self.controller)
         try:
             verify_no_errors(self.controller)
         except AssertionError as e:
             duplicate_group_fail = 1 
-            if (not e.message is "unexpected error type=12 code=1"):
-               raise AssertionError("Incorrect error type: %s" % e.message)
-      	if not duplicate_group_fail:
-           raise AssertionError("Adding duplicate groups didn't raise an error.")
-	        
-	# clean up the test
+            if (not e.message == "unexpected error type=6 code=0"):
+                raise AssertionError("Incorrect error type: %s" % e.message)
+        if not duplicate_group_fail:
+            raise AssertionError("Adding duplicate groups didn't raise an error.")
+                
+        # clean up the test
         group_delete = ofp.message.group_delete(xid = 2, group_id = test_group_id)
         self.controller.message_send(group_delete)
         
-	time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
 class TestGroupAndFlow(base_tests.SimpleDataPlane):
@@ -416,14 +434,14 @@
     def runTest(self):
         logging.info("Running Group tests")
         delete_all_flows(self.controller)
+        delete_all_groups(self.controller)
 
-	# Create a group
-	test_group_id = 1 
-	bucket = ofp.common.bucket(actions=[ofp.action.output(port=onu_port)]) 
-        group_add = ofp.message.group_add(xid = 1, group_type = ofp.OFPGT_ALL, group_id = test_group_id, buckets = [ bucket ])
+        # Create a group
+        test_group_id = 1 
+        group_add = createAllGroupAdd(test_group_id, ports=[onu_port])
 
         self.controller.message_send(group_add)
-        time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
         # Create a flow rule matching olt port and vlan id
@@ -431,7 +449,7 @@
         match.oxm_list.append(ofp.oxm.in_port(olt_port))
         match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | 201))
 
-        request = ofp.message.flow_add(
+        flow_pointing_to_group = ofp.message.flow_add(
             table_id=test_param_get("table", 0),
             cookie=43,
             match=match,
@@ -440,48 +458,40 @@
                     actions=[ ofp.action.group( group_id = test_group_id ) ] ) ],
                     buffer_id=ofp.OFP_NO_BUFFER, priority=1000)
 
-        self.controller.message_send(request)
-	time.sleep(1)
+        self.controller.message_send(flow_pointing_to_group)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
        
-	# After letting a flow rule point to the group, test we can do group_mod
-	onu_port2 = 131
-	bucket = ofp.common.bucket(actions=[ofp.action.output(port=onu_port2)]) 
-	group_mod = ofp.message.group_mod(xid = 2, command = 1, group_type = ofp.OFPGT_ALL, group_id = test_group_id, buckets = [ bucket ])
-	self.controller.message_send(group_mod)
-        time.sleep(1)
+        # After letting a flow rule point to the group, test we can do group_mod
+        group_mod = createAllGroupMod(test_group_id, ports=[onu_port2])
+        self.controller.message_send(group_mod)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
         # Test we can remove flows and then remove group
-        request = ofp.message.flow_delete( table_id=test_param_get("table", 0))
-        self.controller.message_send(request)
-	time.sleep(1)
+        flow_delete = ofp.message.flow_delete( table_id=test_param_get("table", 0))
+        self.controller.message_send(flow_delete)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
         group_delete = ofp.message.group_delete(xid = 3, group_id = test_group_id)
         self.controller.message_send(group_delete)
-	time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
-	# Add the group and flow back, test it we can first remove group and then remove the flow. 
-        group_add = ofp.message.group_add(xid = 1, group_type = ofp.OFPGT_ALL, group_id = test_group_id, buckets = [ bucket ])
+        # Add the group and flow back, test it we can first remove group and then remove the flow. 
+        group_add = createAllGroupAdd(test_group_id, ports=[onu_port])
         self.controller.message_send(group_add)
-	request = ofp.message.flow_add(
-            table_id=test_param_get("table", 0),
-            cookie=43,
-            match=match,
-            instructions=[
-                ofp.instruction.apply_actions(
-                    actions=[ ofp.action.group( group_id = test_group_id ) ] ) ],
-                    buffer_id=ofp.OFP_NO_BUFFER, priority=1000)
-        self.controller.message_send(request)
+
+        self.controller.message_send(flow_pointing_to_group)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
         group_delete = ofp.message.group_delete(xid = 4, group_id = test_group_id)
         self.controller.message_send(group_delete)
-        request = ofp.message.flow_delete( table_id=test_param_get("table", 0))
-        self.controller.message_send(request)
-	time.sleep(1)
+
+        self.controller.message_send(flow_delete)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
 
@@ -490,17 +500,16 @@
     def runTest(self):
         logging.info("Running Group datapath forwarding tests")
         delete_all_flows(self.controller)
+        delete_all_groups(self.controller)
 
-	vlan_id = 200
+        vlan_id = 200
 
-	# Create a group
-	test_group_id = 1 
-	onu_port = 130
-	bucket = ofp.common.bucket(actions=[ofp.action.output(port=onu_port)]) 
-        group_add = ofp.message.group_add(xid = 1, group_type = ofp.OFPGT_ALL, group_id = test_group_id, buckets = [ bucket ])
+        # Create a group
+        test_group_id = 1 
+        group_add = createAllGroupAdd(test_group_id, [onu_port])
 
         self.controller.message_send(group_add)
-        time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
         # Create a flow rule matching olt port and vlan id
@@ -515,39 +524,39 @@
             instructions=[
                 ofp.instruction.apply_actions(
                     actions=[ ofp.action.group( group_id = test_group_id ) ] ), 
-		],
+                ],
                 buffer_id=ofp.OFP_NO_BUFFER, priority=1000)
 
         self.controller.message_send(request)
-	time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
-    	do_barrier(self.controller)
-	time.sleep(5)
+        do_barrier(self.controller)
         
         inPkt = simple_udp_packet(pktlen=104,dl_vlan_enable=True,
                                   vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0)
         outPkt = inPkt
         self.dataplane.send(olt_port, str(inPkt))
         verify_packet(self, outPkt, onu_port)
-        time.sleep(1)
+
+        # Now put 2 ONU ports in the group and test that the input packet is 
+        # duplicated out both ports
+        group_mod = createAllGroupMod(test_group_id, ports=[onu_port, onu_port2])
+        self.controller.message_send(group_mod)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
-
-	#group_mod test
-	#bucket = ofp.common.bucket(actions=[ofp.action.output(port=onu_port), ofp.action.push_vlan(0x0081)]) 
-	#group_mod = ofp.message.group_mod(xid = 1, command = 1, group_type = ofp.OFPGT_ALL, group_id = 2, buckets = [ bucket ])
-
-	#self.controller.message_send(group_mod)
-        #time.sleep(1)
-        #verify_no_errors(self.controller)
+        
+        self.dataplane.send(olt_port, str(inPkt))
+        verify_packet(self, outPkt, onu_port)
+        verify_packet(self, outPkt, onu_port2)
 
 
-	# clean up the test
+        # clean up the test
         request = ofp.message.flow_delete( table_id=test_param_get("table", 0))
         self.controller.message_send(request)
         group_delete = ofp.message.group_delete(xid = 2, group_id = test_group_id)
         self.controller.message_send(group_delete)
         
-	time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
 
 class TransparentVlanTest(base_tests.SimpleDataPlane):
@@ -555,7 +564,7 @@
     def runTest(self):
         logging.info("Running transparent vlan tests")
 
-	vlan_id = 201
+        vlan_id = 201
         match = ofp.match()
         match.oxm_list.append(ofp.oxm.in_port(onu_port))
         match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id ))
@@ -573,8 +582,6 @@
             priority=1000)
 
         self.controller.message_send(request)
-        time.sleep(1)
-        verify_no_errors(self.controller)
  
         match = ofp.match()
         match.oxm_list.append(ofp.oxm.in_port(olt_port))
@@ -593,12 +600,12 @@
             priority=1000)
 
         self.controller.message_send(request)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)
-    	do_barrier(self.controller)
-        time.sleep(5)
+
         
-	inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=(vlan_id), vlan_pcp=0)
-	# downstream
+        inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=vlan_id, vlan_pcp=0)
+        # downstream
         self.dataplane.send(olt_port, str(inPkt))
         verify_packet(self, inPkt, onu_port)
         # upstream
@@ -606,9 +613,9 @@
         verify_packet(self, inPkt, olt_port)
         
 
-	# clean up the test
+        # clean up the test
         delete_all_flows(self.controller)
-        time.sleep(1)
+        do_barrier(self.controller)
         verify_no_errors(self.controller)