Fix checkstyle whitespace issues - WHITESPACE ONLY
Change-Id: Ic205c1afd639c6008d61d9de95cb764eeb6238ca
diff --git a/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java
index be7834c..1c25e75 100644
--- a/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java
+++ b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java
@@ -41,515 +41,517 @@
import org.openflow.protocol.factory.BasicFactory;
public class FlowPusherTest {
- private FlowPusher pusher;
- private FloodlightContext context;
- private FloodlightModuleContext modContext;
- private BasicFactory factory;
- private OFMessageDamper damper;
- private IFloodlightProviderService flProviderService;
- private IThreadPoolService threadPoolService;
+ private FlowPusher pusher;
+ private FloodlightContext context;
+ private FloodlightModuleContext modContext;
+ private BasicFactory factory;
+ private OFMessageDamper damper;
+ private IFloodlightProviderService flProviderService;
+ private IThreadPoolService threadPoolService;
- /**
- * Test single OFMessage is correctly sent to single switch via MessageDamper.
- */
- @Test
- public void testAddMessage() {
- beginInitMock();
-
- OFMessage msg = EasyMock.createMock(OFMessage.class);
- EasyMock.expect(msg.getXid()).andReturn(1).anyTimes();
- EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
- EasyMock.replay(msg);
-
- IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
- EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
- sw.flush();
- EasyMock.expectLastCall().once();
- EasyMock.replay(sw);
-
- try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
- .andReturn(true).once();
- } catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
- }
-
- endInitMock();
- initPusher(1);
-
- boolean add_result = pusher.add(sw, msg);
- assertTrue(add_result);
-
- try {
- // wait until message is processed.
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- fail("Failed in Thread.sleep()");
- }
- EasyMock.verify(msg);
- EasyMock.verify(sw);
- verifyAll();
-
- pusher.stop();
- }
-
- /**
- * Test bunch of OFMessages are correctly sent to single switch via MessageDamper.
- */
- @Test
- public void testMassiveAddMessage() {
- final int NUM_MSG = 10000;
-
- beginInitMock();
+ /**
+ * Test single OFMessage is correctly sent to single switch via MessageDamper.
+ */
+ @Test
+ public void testAddMessage() {
+ beginInitMock();
- IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
- EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
- sw.flush();
- EasyMock.expectLastCall().atLeastOnce();
- EasyMock.replay(sw);
-
- List<OFMessage> messages = new ArrayList<OFMessage>();
-
- for (int i = 0; i < NUM_MSG; ++i) {
- OFMessage msg = EasyMock.createMock(OFMessage.class);
- EasyMock.expect(msg.getXid()).andReturn(i).anyTimes();
- EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
- EasyMock.replay(msg);
- messages.add(msg);
-
- try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
- .andReturn(true).once();
- } catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
- }
- }
-
- endInitMock();
- initPusher(1);
-
- for (OFMessage msg : messages) {
- boolean add_result = pusher.add(sw, msg);
- assertTrue(add_result);
- }
-
- try {
- // wait until message is processed.
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- fail("Failed in Thread.sleep()");
- }
-
- for (OFMessage msg : messages) {
- EasyMock.verify(msg);
- }
- EasyMock.verify(sw);
- verifyAll();
-
- pusher.stop();
- }
-
- /**
- * Test bunch of OFMessages are correctly sent to multiple switches with single threads.
- */
- @Test
- public void testMultiSwitchAddMessage() {
- final int NUM_SWITCH = 10;
- final int NUM_MSG = 100; // messages per thread
-
- beginInitMock();
+ OFMessage msg = EasyMock.createMock(OFMessage.class);
+ EasyMock.expect(msg.getXid()).andReturn(1).anyTimes();
+ EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+ EasyMock.replay(msg);
- Map<IOFSwitch, List<OFMessage>> sw_map = new HashMap<IOFSwitch, List<OFMessage>>();
- for (int i = 0; i < NUM_SWITCH; ++i) {
- IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
- EasyMock.expect(sw.getId()).andReturn((long)i).anyTimes();
- sw.flush();
- EasyMock.expectLastCall().atLeastOnce();
- EasyMock.replay(sw);
-
- List<OFMessage> messages = new ArrayList<OFMessage>();
-
- for (int j = 0; j < NUM_MSG; ++j) {
- OFMessage msg = EasyMock.createMock(OFMessage.class);
- EasyMock.expect(msg.getXid()).andReturn(j).anyTimes();
- EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
- EasyMock.replay(msg);
- messages.add(msg);
-
- try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
- .andReturn(true).once();
- } catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
- }
- }
- sw_map.put(sw, messages);
- }
-
- endInitMock();
- initPusher(1);
-
- for (IOFSwitch sw : sw_map.keySet()) {
- for (OFMessage msg : sw_map.get(sw)) {
- boolean add_result = pusher.add(sw, msg);
- assertTrue(add_result);
- }
- }
-
- try {
- // wait until message is processed.
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- fail("Failed in Thread.sleep()");
- }
-
- for (IOFSwitch sw : sw_map.keySet()) {
- for (OFMessage msg : sw_map.get(sw)) {
- EasyMock.verify(msg);
- }
-
- EasyMock.verify(sw);
- }
- verifyAll();
+ IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
+ EasyMock.expect(sw.getId()).andReturn((long) 1).anyTimes();
+ sw.flush();
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(sw);
- pusher.stop();
- }
-
- /**
- * Test bunch of OFMessages are correctly sent to multiple switches using multiple threads.
- */
- @Test
- public void testMultiThreadedAddMessage() {
- final int NUM_THREAD = 10;
- final int NUM_MSG = 100; // messages per thread
-
- beginInitMock();
+ try {
+ EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
+ .andReturn(true).once();
+ } catch (IOException e1) {
+ fail("Failed in OFMessageDamper#write()");
+ }
- Map<IOFSwitch, List<OFMessage>> sw_map = new HashMap<IOFSwitch, List<OFMessage>>();
- for (int i = 0; i < NUM_THREAD; ++i) {
- IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
- EasyMock.expect(sw.getId()).andReturn((long)i).anyTimes();
- sw.flush();
- EasyMock.expectLastCall().atLeastOnce();
- EasyMock.replay(sw);
-
- List<OFMessage> messages = new ArrayList<OFMessage>();
-
- for (int j = 0; j < NUM_MSG; ++j) {
- OFMessage msg = EasyMock.createMock(OFMessage.class);
- EasyMock.expect(msg.getXid()).andReturn(j).anyTimes();
- EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
- EasyMock.replay(msg);
- messages.add(msg);
-
- try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
- .andReturn(true).once();
- } catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
- }
- }
- sw_map.put(sw, messages);
- }
-
- endInitMock();
- initPusher(NUM_THREAD);
-
- for (IOFSwitch sw : sw_map.keySet()) {
- for (OFMessage msg : sw_map.get(sw)) {
- boolean add_result = pusher.add(sw, msg);
- assertTrue(add_result);
- }
- }
-
- try {
- // wait until message is processed.
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- fail("Failed in Thread.sleep()");
- }
-
- for (IOFSwitch sw : sw_map.keySet()) {
- for (OFMessage msg : sw_map.get(sw)) {
- EasyMock.verify(msg);
- }
-
- EasyMock.verify(sw);
- }
- verifyAll();
+ endInitMock();
+ initPusher(1);
- pusher.stop();
- }
-
- private long barrierTime = 0;
- /**
- * Test rate limitation of messages works correctly.
- */
- @Test
- public void testRateLimitedAddMessage() {
- final long LIMIT_RATE = 100; // [bytes/ms]
- final int NUM_MSG = 1000;
-
- // Accuracy of FlowPusher's rate calculation can't be measured by unit test
- // because switch doesn't return BARRIER_REPLY.
- // In unit test we use approximate way to measure rate. This value is
- // acceptable margin of measured rate.
- final double ACCEPTABLE_RATE = LIMIT_RATE * 1.2;
-
- beginInitMock();
+ boolean add_result = pusher.add(sw, msg);
+ assertTrue(add_result);
- IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
- EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
- sw.flush();
- EasyMock.expectLastCall().atLeastOnce();
- prepareBarrier(sw);
- EasyMock.replay(sw);
-
- List<OFMessage> messages = new ArrayList<OFMessage>();
-
- for (int i = 0; i < NUM_MSG; ++i) {
- OFMessage msg = EasyMock.createMock(OFMessage.class);
- EasyMock.expect(msg.getXid()).andReturn(1).anyTimes();
- EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
- EasyMock.expect(msg.getLengthU()).andReturn(100).anyTimes();
- EasyMock.replay(msg);
- messages.add(msg);
-
- try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
- .andReturn(true).once();
- } catch (IOException e) {
- fail("Failed in OFMessageDamper#write()");
- }
- }
-
- try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), (OFMessage)EasyMock.anyObject(), EasyMock.eq(context)))
- .andAnswer(new IAnswer<Boolean>() {
- @Override
- public Boolean answer() throws Throwable {
- OFMessage msg = (OFMessage)EasyMock.getCurrentArguments()[1];
- if (msg.getType() == OFType.BARRIER_REQUEST) {
- barrierTime = System.currentTimeMillis();
- }
- return true;
- }
- }).once();
- } catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
- }
+ try {
+ // wait until message is processed.
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ fail("Failed in Thread.sleep()");
+ }
+ EasyMock.verify(msg);
+ EasyMock.verify(sw);
+ verifyAll();
- endInitMock();
- initPusher(1);
-
- pusher.createQueue(sw);
- pusher.setRate(sw, LIMIT_RATE);
-
- long beginTime = System.currentTimeMillis();
- for (OFMessage msg : messages) {
- boolean add_result = pusher.add(sw, msg);
- assertTrue(add_result);
- }
-
- pusher.barrierAsync(sw);
+ pusher.stop();
+ }
- try {
- do {
- Thread.sleep(1000);
- } while (barrierTime == 0);
- } catch (InterruptedException e) {
- fail("Failed to sleep");
- }
-
- double measured_rate = NUM_MSG * 100 / (barrierTime - beginTime);
- assertTrue(measured_rate < ACCEPTABLE_RATE);
-
- for (OFMessage msg : messages) {
- EasyMock.verify(msg);
- }
- EasyMock.verify(sw);
- verifyAll();
+ /**
+ * Test bunch of OFMessages are correctly sent to single switch via MessageDamper.
+ */
+ @Test
+ public void testMassiveAddMessage() {
+ final int NUM_MSG = 10000;
- pusher.stop();
- }
+ beginInitMock();
- /**
- * Test barrier message is correctly sent to a switch.
- */
- @Test
- public void testBarrierMessage() {
- beginInitMock();
-
- IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
- EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
- sw.flush();
- EasyMock.expectLastCall().atLeastOnce();
- prepareBarrier(sw);
- EasyMock.replay(sw);
+ IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
+ EasyMock.expect(sw.getId()).andReturn((long) 1).anyTimes();
+ sw.flush();
+ EasyMock.expectLastCall().atLeastOnce();
+ EasyMock.replay(sw);
- try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), (OFMessage)EasyMock.anyObject(), EasyMock.eq(context)))
- .andReturn(true).once();
- } catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
- }
+ List<OFMessage> messages = new ArrayList<OFMessage>();
- endInitMock();
- initPusher(1);
+ for (int i = 0; i < NUM_MSG; ++i) {
+ OFMessage msg = EasyMock.createMock(OFMessage.class);
+ EasyMock.expect(msg.getXid()).andReturn(i).anyTimes();
+ EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+ EasyMock.replay(msg);
+ messages.add(msg);
- OFBarrierReplyFuture future = pusher.barrierAsync(sw);
-
- assertNotNull(future);
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- fail("Failed to sleep");
- }
-
- verifyAll();
+ try {
+ EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
+ .andReturn(true).once();
+ } catch (IOException e1) {
+ fail("Failed in OFMessageDamper#write()");
+ }
+ }
- pusher.stop();
- }
-
- static final int XID_TO_VERIFY = 100;
- static final long DPID_TO_VERIFY = 10;
- /**
- * Test FlowObject is correctly converted to message and is sent to a switch.
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testAddFlow() {
- // instantiate required objects
- FlowEntry flowEntry1 = new FlowEntry();
- flowEntry1.setDpid(new Dpid(DPID_TO_VERIFY));
- flowEntry1.setFlowId(new FlowId(1));
- flowEntry1.setInPort(new Port((short) 1));
- flowEntry1.setOutPort(new Port((short) 11));
- flowEntry1.setFlowEntryId(new FlowEntryId(1));
- flowEntry1.setFlowEntryMatch(new FlowEntryMatch());
- flowEntry1.setFlowEntryActions(new FlowEntryActions());
- flowEntry1.setFlowEntryErrorState(new FlowEntryErrorState());
- flowEntry1.setFlowEntryUserState(FlowEntryUserState.FE_USER_ADD);
-
- beginInitMock();
-
- OFFlowMod msg = EasyMock.createMock(OFFlowMod.class);
- EasyMock.expect(msg.setIdleTimeout(EasyMock.anyShort())).andReturn(msg);
- EasyMock.expect(msg.setHardTimeout(EasyMock.anyShort())).andReturn(msg);
- EasyMock.expect(msg.setPriority(EasyMock.anyShort())).andReturn(msg);
- EasyMock.expect(msg.setBufferId(EasyMock.anyInt())).andReturn(msg);
- EasyMock.expect(msg.setCookie(EasyMock.anyLong())).andReturn(msg);
- EasyMock.expect(msg.setCommand(EasyMock.anyShort())).andReturn(msg);
- EasyMock.expect(msg.setMatch(EasyMock.anyObject(OFMatch.class))).andReturn(msg);
- EasyMock.expect(msg.setActions((List<OFAction>)EasyMock.anyObject())).andReturn(msg);
- EasyMock.expect(msg.setLengthU(EasyMock.anyShort())).andReturn(msg);
- EasyMock.expect(msg.setOutPort(EasyMock.anyShort())).andReturn(msg).atLeastOnce();
- EasyMock.expect(msg.getXid()).andReturn(XID_TO_VERIFY).anyTimes();
- EasyMock.expect(msg.getType()).andReturn(OFType.FLOW_MOD).anyTimes();
- EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
- EasyMock.replay(msg);
-
- EasyMock.expect(factory.getMessage(EasyMock.eq(OFType.FLOW_MOD))).andReturn(msg);
+ endInitMock();
+ initPusher(1);
- IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
- EasyMock.expect(sw.getId()).andReturn(DPID_TO_VERIFY).anyTimes();
- EasyMock.expect(sw.getStringId()).andReturn("1").anyTimes();
- sw.flush();
- EasyMock.expectLastCall().once();
-
- try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.anyObject(OFMessage.class), EasyMock.eq(context)))
- .andAnswer(new IAnswer<Boolean>() {
- @Override
- public Boolean answer() throws Throwable {
- OFMessage msg = (OFMessage)EasyMock.getCurrentArguments()[1];
- if (msg.getType() == OFType.FLOW_MOD) {
- assertEquals(msg.getXid(), XID_TO_VERIFY);
- }
- return true;
- }
- }).atLeastOnce();
- } catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
- }
-
- EasyMock.replay(sw);
-
- endInitMock();
- initPusher(1);
+ for (OFMessage msg : messages) {
+ boolean add_result = pusher.add(sw, msg);
+ assertTrue(add_result);
+ }
- pusher.pushFlowEntry(sw, flowEntry1);
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- fail("Failed to sleep");
- }
-
- EasyMock.verify(sw);
- verifyAll();
+ try {
+ // wait until message is processed.
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ fail("Failed in Thread.sleep()");
+ }
- pusher.stop();
- }
-
- private void beginInitMock() {
- context = EasyMock.createMock(FloodlightContext.class);
- modContext = EasyMock.createMock(FloodlightModuleContext.class);
- factory = EasyMock.createMock(BasicFactory.class);
- damper = EasyMock.createMock(OFMessageDamper.class);
- flProviderService = EasyMock.createMock(IFloodlightProviderService.class);
- threadPoolService = EasyMock.createMock(IThreadPoolService.class);
-
- EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IThreadPoolService.class)))
- .andReturn(threadPoolService).once();
- EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IFloodlightProviderService.class)))
- .andReturn(flProviderService).once();
- flProviderService.addOFMessageListener(EasyMock.eq(OFType.BARRIER_REPLY),
- (FlowPusher) EasyMock.anyObject());
- EasyMock.expectLastCall().once();
-
- ScheduledExecutorService executor = EasyMock.createMock(ScheduledExecutorService.class);
- EasyMock.expect(executor.schedule((Runnable)EasyMock.anyObject(), EasyMock.anyLong(),
- (TimeUnit)EasyMock.anyObject())).andReturn(null).once();
- EasyMock.replay(executor);
- EasyMock.expect(threadPoolService.getScheduledExecutor()).andReturn(executor).anyTimes();
- }
-
- private void endInitMock() {
- EasyMock.replay(threadPoolService);
- EasyMock.replay(flProviderService);
- EasyMock.replay(damper);
- EasyMock.replay(factory);
- EasyMock.replay(modContext);
- EasyMock.replay(context);
- }
-
- private void verifyAll() {
- EasyMock.verify(threadPoolService);
- EasyMock.verify(flProviderService);
- EasyMock.verify(damper);
- EasyMock.verify(factory);
- EasyMock.verify(modContext);
- EasyMock.verify(context);
- }
-
- private void initPusher(int num_thread) {
- pusher = new FlowPusher(num_thread);
- pusher.init(context, modContext, factory, damper);
- pusher.start();
- }
-
- private void prepareBarrier(IOFSwitch sw) {
- OFBarrierRequest req = EasyMock.createMock(OFBarrierRequest.class);
- req.setXid(EasyMock.anyInt());
- EasyMock.expectLastCall().once();
- EasyMock.expect(req.getXid()).andReturn(1).anyTimes();
- EasyMock.expect(req.getType()).andReturn(OFType.BARRIER_REQUEST).anyTimes();
- EasyMock.expect(req.getLength()).andReturn((short)100).anyTimes();
- EasyMock.replay(req);
- EasyMock.expect(factory.getMessage(EasyMock.eq(OFType.BARRIER_REQUEST))).andReturn(req).anyTimes();
- EasyMock.expect(sw.getNextTransactionId()).andReturn(1);
- }
-
+ for (OFMessage msg : messages) {
+ EasyMock.verify(msg);
+ }
+ EasyMock.verify(sw);
+ verifyAll();
+
+ pusher.stop();
+ }
+
+ /**
+ * Test bunch of OFMessages are correctly sent to multiple switches with single threads.
+ */
+ @Test
+ public void testMultiSwitchAddMessage() {
+ final int NUM_SWITCH = 10;
+ final int NUM_MSG = 100; // messages per thread
+
+ beginInitMock();
+
+ Map<IOFSwitch, List<OFMessage>> sw_map = new HashMap<IOFSwitch, List<OFMessage>>();
+ for (int i = 0; i < NUM_SWITCH; ++i) {
+ IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
+ EasyMock.expect(sw.getId()).andReturn((long) i).anyTimes();
+ sw.flush();
+ EasyMock.expectLastCall().atLeastOnce();
+ EasyMock.replay(sw);
+
+ List<OFMessage> messages = new ArrayList<OFMessage>();
+
+ for (int j = 0; j < NUM_MSG; ++j) {
+ OFMessage msg = EasyMock.createMock(OFMessage.class);
+ EasyMock.expect(msg.getXid()).andReturn(j).anyTimes();
+ EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+ EasyMock.replay(msg);
+ messages.add(msg);
+
+ try {
+ EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
+ .andReturn(true).once();
+ } catch (IOException e1) {
+ fail("Failed in OFMessageDamper#write()");
+ }
+ }
+ sw_map.put(sw, messages);
+ }
+
+ endInitMock();
+ initPusher(1);
+
+ for (IOFSwitch sw : sw_map.keySet()) {
+ for (OFMessage msg : sw_map.get(sw)) {
+ boolean add_result = pusher.add(sw, msg);
+ assertTrue(add_result);
+ }
+ }
+
+ try {
+ // wait until message is processed.
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ fail("Failed in Thread.sleep()");
+ }
+
+ for (IOFSwitch sw : sw_map.keySet()) {
+ for (OFMessage msg : sw_map.get(sw)) {
+ EasyMock.verify(msg);
+ }
+
+ EasyMock.verify(sw);
+ }
+ verifyAll();
+
+ pusher.stop();
+ }
+
+ /**
+ * Test bunch of OFMessages are correctly sent to multiple switches using multiple threads.
+ */
+ @Test
+ public void testMultiThreadedAddMessage() {
+ final int NUM_THREAD = 10;
+ final int NUM_MSG = 100; // messages per thread
+
+ beginInitMock();
+
+ Map<IOFSwitch, List<OFMessage>> sw_map = new HashMap<IOFSwitch, List<OFMessage>>();
+ for (int i = 0; i < NUM_THREAD; ++i) {
+ IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
+ EasyMock.expect(sw.getId()).andReturn((long) i).anyTimes();
+ sw.flush();
+ EasyMock.expectLastCall().atLeastOnce();
+ EasyMock.replay(sw);
+
+ List<OFMessage> messages = new ArrayList<OFMessage>();
+
+ for (int j = 0; j < NUM_MSG; ++j) {
+ OFMessage msg = EasyMock.createMock(OFMessage.class);
+ EasyMock.expect(msg.getXid()).andReturn(j).anyTimes();
+ EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+ EasyMock.replay(msg);
+ messages.add(msg);
+
+ try {
+ EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
+ .andReturn(true).once();
+ } catch (IOException e1) {
+ fail("Failed in OFMessageDamper#write()");
+ }
+ }
+ sw_map.put(sw, messages);
+ }
+
+ endInitMock();
+ initPusher(NUM_THREAD);
+
+ for (IOFSwitch sw : sw_map.keySet()) {
+ for (OFMessage msg : sw_map.get(sw)) {
+ boolean add_result = pusher.add(sw, msg);
+ assertTrue(add_result);
+ }
+ }
+
+ try {
+ // wait until message is processed.
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ fail("Failed in Thread.sleep()");
+ }
+
+ for (IOFSwitch sw : sw_map.keySet()) {
+ for (OFMessage msg : sw_map.get(sw)) {
+ EasyMock.verify(msg);
+ }
+
+ EasyMock.verify(sw);
+ }
+ verifyAll();
+
+ pusher.stop();
+ }
+
+ private long barrierTime = 0;
+
+ /**
+ * Test rate limitation of messages works correctly.
+ */
+ @Test
+ public void testRateLimitedAddMessage() {
+ final long LIMIT_RATE = 100; // [bytes/ms]
+ final int NUM_MSG = 1000;
+
+ // Accuracy of FlowPusher's rate calculation can't be measured by unit test
+ // because switch doesn't return BARRIER_REPLY.
+ // In unit test we use approximate way to measure rate. This value is
+ // acceptable margin of measured rate.
+ final double ACCEPTABLE_RATE = LIMIT_RATE * 1.2;
+
+ beginInitMock();
+
+ IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
+ EasyMock.expect(sw.getId()).andReturn((long) 1).anyTimes();
+ sw.flush();
+ EasyMock.expectLastCall().atLeastOnce();
+ prepareBarrier(sw);
+ EasyMock.replay(sw);
+
+ List<OFMessage> messages = new ArrayList<OFMessage>();
+
+ for (int i = 0; i < NUM_MSG; ++i) {
+ OFMessage msg = EasyMock.createMock(OFMessage.class);
+ EasyMock.expect(msg.getXid()).andReturn(1).anyTimes();
+ EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+ EasyMock.expect(msg.getLengthU()).andReturn(100).anyTimes();
+ EasyMock.replay(msg);
+ messages.add(msg);
+
+ try {
+ EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
+ .andReturn(true).once();
+ } catch (IOException e) {
+ fail("Failed in OFMessageDamper#write()");
+ }
+ }
+
+ try {
+ EasyMock.expect(damper.write(EasyMock.eq(sw), (OFMessage) EasyMock.anyObject(), EasyMock.eq(context)))
+ .andAnswer(new IAnswer<Boolean>() {
+ @Override
+ public Boolean answer() throws Throwable {
+ OFMessage msg = (OFMessage) EasyMock.getCurrentArguments()[1];
+ if (msg.getType() == OFType.BARRIER_REQUEST) {
+ barrierTime = System.currentTimeMillis();
+ }
+ return true;
+ }
+ }).once();
+ } catch (IOException e1) {
+ fail("Failed in OFMessageDamper#write()");
+ }
+
+ endInitMock();
+ initPusher(1);
+
+ pusher.createQueue(sw);
+ pusher.setRate(sw, LIMIT_RATE);
+
+ long beginTime = System.currentTimeMillis();
+ for (OFMessage msg : messages) {
+ boolean add_result = pusher.add(sw, msg);
+ assertTrue(add_result);
+ }
+
+ pusher.barrierAsync(sw);
+
+ try {
+ do {
+ Thread.sleep(1000);
+ } while (barrierTime == 0);
+ } catch (InterruptedException e) {
+ fail("Failed to sleep");
+ }
+
+ double measured_rate = NUM_MSG * 100 / (barrierTime - beginTime);
+ assertTrue(measured_rate < ACCEPTABLE_RATE);
+
+ for (OFMessage msg : messages) {
+ EasyMock.verify(msg);
+ }
+ EasyMock.verify(sw);
+ verifyAll();
+
+ pusher.stop();
+ }
+
+ /**
+ * Test barrier message is correctly sent to a switch.
+ */
+ @Test
+ public void testBarrierMessage() {
+ beginInitMock();
+
+ IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
+ EasyMock.expect(sw.getId()).andReturn((long) 1).anyTimes();
+ sw.flush();
+ EasyMock.expectLastCall().atLeastOnce();
+ prepareBarrier(sw);
+ EasyMock.replay(sw);
+
+ try {
+ EasyMock.expect(damper.write(EasyMock.eq(sw), (OFMessage) EasyMock.anyObject(), EasyMock.eq(context)))
+ .andReturn(true).once();
+ } catch (IOException e1) {
+ fail("Failed in OFMessageDamper#write()");
+ }
+
+ endInitMock();
+ initPusher(1);
+
+ OFBarrierReplyFuture future = pusher.barrierAsync(sw);
+
+ assertNotNull(future);
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ fail("Failed to sleep");
+ }
+
+ verifyAll();
+
+ pusher.stop();
+ }
+
+ static final int XID_TO_VERIFY = 100;
+ static final long DPID_TO_VERIFY = 10;
+
+ /**
+ * Test FlowObject is correctly converted to message and is sent to a switch.
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testAddFlow() {
+ // instantiate required objects
+ FlowEntry flowEntry1 = new FlowEntry();
+ flowEntry1.setDpid(new Dpid(DPID_TO_VERIFY));
+ flowEntry1.setFlowId(new FlowId(1));
+ flowEntry1.setInPort(new Port((short) 1));
+ flowEntry1.setOutPort(new Port((short) 11));
+ flowEntry1.setFlowEntryId(new FlowEntryId(1));
+ flowEntry1.setFlowEntryMatch(new FlowEntryMatch());
+ flowEntry1.setFlowEntryActions(new FlowEntryActions());
+ flowEntry1.setFlowEntryErrorState(new FlowEntryErrorState());
+ flowEntry1.setFlowEntryUserState(FlowEntryUserState.FE_USER_ADD);
+
+ beginInitMock();
+
+ OFFlowMod msg = EasyMock.createMock(OFFlowMod.class);
+ EasyMock.expect(msg.setIdleTimeout(EasyMock.anyShort())).andReturn(msg);
+ EasyMock.expect(msg.setHardTimeout(EasyMock.anyShort())).andReturn(msg);
+ EasyMock.expect(msg.setPriority(EasyMock.anyShort())).andReturn(msg);
+ EasyMock.expect(msg.setBufferId(EasyMock.anyInt())).andReturn(msg);
+ EasyMock.expect(msg.setCookie(EasyMock.anyLong())).andReturn(msg);
+ EasyMock.expect(msg.setCommand(EasyMock.anyShort())).andReturn(msg);
+ EasyMock.expect(msg.setMatch(EasyMock.anyObject(OFMatch.class))).andReturn(msg);
+ EasyMock.expect(msg.setActions((List<OFAction>) EasyMock.anyObject())).andReturn(msg);
+ EasyMock.expect(msg.setLengthU(EasyMock.anyShort())).andReturn(msg);
+ EasyMock.expect(msg.setOutPort(EasyMock.anyShort())).andReturn(msg).atLeastOnce();
+ EasyMock.expect(msg.getXid()).andReturn(XID_TO_VERIFY).anyTimes();
+ EasyMock.expect(msg.getType()).andReturn(OFType.FLOW_MOD).anyTimes();
+ EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+ EasyMock.replay(msg);
+
+ EasyMock.expect(factory.getMessage(EasyMock.eq(OFType.FLOW_MOD))).andReturn(msg);
+
+ IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
+ EasyMock.expect(sw.getId()).andReturn(DPID_TO_VERIFY).anyTimes();
+ EasyMock.expect(sw.getStringId()).andReturn("1").anyTimes();
+ sw.flush();
+ EasyMock.expectLastCall().once();
+
+ try {
+ EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.anyObject(OFMessage.class), EasyMock.eq(context)))
+ .andAnswer(new IAnswer<Boolean>() {
+ @Override
+ public Boolean answer() throws Throwable {
+ OFMessage msg = (OFMessage) EasyMock.getCurrentArguments()[1];
+ if (msg.getType() == OFType.FLOW_MOD) {
+ assertEquals(msg.getXid(), XID_TO_VERIFY);
+ }
+ return true;
+ }
+ }).atLeastOnce();
+ } catch (IOException e1) {
+ fail("Failed in OFMessageDamper#write()");
+ }
+
+ EasyMock.replay(sw);
+
+ endInitMock();
+ initPusher(1);
+
+ pusher.pushFlowEntry(sw, flowEntry1);
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ fail("Failed to sleep");
+ }
+
+ EasyMock.verify(sw);
+ verifyAll();
+
+ pusher.stop();
+ }
+
+ private void beginInitMock() {
+ context = EasyMock.createMock(FloodlightContext.class);
+ modContext = EasyMock.createMock(FloodlightModuleContext.class);
+ factory = EasyMock.createMock(BasicFactory.class);
+ damper = EasyMock.createMock(OFMessageDamper.class);
+ flProviderService = EasyMock.createMock(IFloodlightProviderService.class);
+ threadPoolService = EasyMock.createMock(IThreadPoolService.class);
+
+ EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IThreadPoolService.class)))
+ .andReturn(threadPoolService).once();
+ EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IFloodlightProviderService.class)))
+ .andReturn(flProviderService).once();
+ flProviderService.addOFMessageListener(EasyMock.eq(OFType.BARRIER_REPLY),
+ (FlowPusher) EasyMock.anyObject());
+ EasyMock.expectLastCall().once();
+
+ ScheduledExecutorService executor = EasyMock.createMock(ScheduledExecutorService.class);
+ EasyMock.expect(executor.schedule((Runnable) EasyMock.anyObject(), EasyMock.anyLong(),
+ (TimeUnit) EasyMock.anyObject())).andReturn(null).once();
+ EasyMock.replay(executor);
+ EasyMock.expect(threadPoolService.getScheduledExecutor()).andReturn(executor).anyTimes();
+ }
+
+ private void endInitMock() {
+ EasyMock.replay(threadPoolService);
+ EasyMock.replay(flProviderService);
+ EasyMock.replay(damper);
+ EasyMock.replay(factory);
+ EasyMock.replay(modContext);
+ EasyMock.replay(context);
+ }
+
+ private void verifyAll() {
+ EasyMock.verify(threadPoolService);
+ EasyMock.verify(flProviderService);
+ EasyMock.verify(damper);
+ EasyMock.verify(factory);
+ EasyMock.verify(modContext);
+ EasyMock.verify(context);
+ }
+
+ private void initPusher(int num_thread) {
+ pusher = new FlowPusher(num_thread);
+ pusher.init(context, modContext, factory, damper);
+ pusher.start();
+ }
+
+ private void prepareBarrier(IOFSwitch sw) {
+ OFBarrierRequest req = EasyMock.createMock(OFBarrierRequest.class);
+ req.setXid(EasyMock.anyInt());
+ EasyMock.expectLastCall().once();
+ EasyMock.expect(req.getXid()).andReturn(1).anyTimes();
+ EasyMock.expect(req.getType()).andReturn(OFType.BARRIER_REQUEST).anyTimes();
+ EasyMock.expect(req.getLength()).andReturn((short) 100).anyTimes();
+ EasyMock.replay(req);
+ EasyMock.expect(factory.getMessage(EasyMock.eq(OFType.BARRIER_REQUEST))).andReturn(req).anyTimes();
+ EasyMock.expect(sw.getNextTransactionId()).andReturn(1);
+ }
+
}
diff --git a/src/test/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizerTest.java b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizerTest.java
index 9222a8a..2d97d4f 100644
--- a/src/test/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizerTest.java
+++ b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizerTest.java
@@ -37,286 +37,290 @@
@RunWith(PowerMockRunner.class)
@PrepareForTest({FlowSynchronizer.class})
public class FlowSynchronizerTest {
- private FlowPusher pusher;
- private FlowSynchronizer sync;
- private List<Long> idAdded;
- private List<Long> idRemoved;
+ private FlowPusher pusher;
+ private FlowSynchronizer sync;
+ private List<Long> idAdded;
+ private List<Long> idRemoved;
- @Before
- public void setUp() throws Exception {
- idAdded = new ArrayList<Long>();
- idRemoved = new ArrayList<Long>();
-
- pusher = EasyMock.createMock(FlowPusher.class);
- EasyMock.expect(pusher.suspend(EasyMock.anyObject(IOFSwitch.class))).andReturn(true).anyTimes();
- EasyMock.expect(pusher.resume(EasyMock.anyObject(IOFSwitch.class))).andReturn(true).anyTimes();
- pusher.add(EasyMock.anyObject(IOFSwitch.class), EasyMock.anyObject(OFMessage.class),
- EasyMock.eq(MsgPriority.HIGH));
- EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
- @Override
- public Object answer() throws Throwable {
- OFMessage msg = (OFMessage)EasyMock.getCurrentArguments()[1];
- if (msg.getType().equals(OFType.FLOW_MOD)) {
- OFFlowMod fm = (OFFlowMod)msg;
- if (fm.getCommand() == OFFlowMod.OFPFC_DELETE_STRICT) {
- idRemoved.add(fm.getCookie());
- }
- }
- return null;
- }
- }).anyTimes();
- pusher.pushFlowEntry(EasyMock.anyObject(IOFSwitch.class), EasyMock.anyObject(FlowEntry.class),
- EasyMock.eq(MsgPriority.HIGH));
- EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
- @Override
- public Object answer() throws Throwable {
- FlowEntry flow = (FlowEntry)EasyMock.getCurrentArguments()[1];
- idAdded.add(flow.flowEntryId().value());
- return null;
- }
- }).anyTimes();
- EasyMock.replay(pusher);
- }
+ @Before
+ public void setUp() throws Exception {
+ idAdded = new ArrayList<Long>();
+ idRemoved = new ArrayList<Long>();
- @After
- public void tearDown() throws Exception {
- }
+ pusher = EasyMock.createMock(FlowPusher.class);
+ EasyMock.expect(pusher.suspend(EasyMock.anyObject(IOFSwitch.class))).andReturn(true).anyTimes();
+ EasyMock.expect(pusher.resume(EasyMock.anyObject(IOFSwitch.class))).andReturn(true).anyTimes();
+ pusher.add(EasyMock.anyObject(IOFSwitch.class), EasyMock.anyObject(OFMessage.class),
+ EasyMock.eq(MsgPriority.HIGH));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ OFMessage msg = (OFMessage) EasyMock.getCurrentArguments()[1];
+ if (msg.getType().equals(OFType.FLOW_MOD)) {
+ OFFlowMod fm = (OFFlowMod) msg;
+ if (fm.getCommand() == OFFlowMod.OFPFC_DELETE_STRICT) {
+ idRemoved.add(fm.getCookie());
+ }
+ }
+ return null;
+ }
+ }).anyTimes();
+ pusher.pushFlowEntry(EasyMock.anyObject(IOFSwitch.class), EasyMock.anyObject(FlowEntry.class),
+ EasyMock.eq(MsgPriority.HIGH));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ FlowEntry flow = (FlowEntry) EasyMock.getCurrentArguments()[1];
+ idAdded.add(flow.flowEntryId().value());
+ return null;
+ }
+ }).anyTimes();
+ EasyMock.replay(pusher);
+ }
- /**
- * Test that synchronization doesn't affect anything in case either DB and
- * flow table has the same entries.
- */
- @Test
- public void testStable() {
- // Create mock of flow table : flow 1
- IOFSwitch sw = createMockSwitch(new long[] {1});
-
- // Create mock of flow entries : flow 1
- initMockGraph(new long[] {1});
-
- // synchronize
- doSynchronization(sw);
-
- // check if flow is not changed
- assertEquals(0, idAdded.size());
- assertEquals(0, idRemoved.size());
- }
+ @After
+ public void tearDown() throws Exception {
+ }
- /**
- * Test that an flow is added in case DB has an extra FlowEntry.
- */
- @Test
- public void testSingleAdd() {
- // Create mock of flow table : null
- IOFSwitch sw = createMockSwitch(new long[] {});
-
- // Create mock of flow entries : flow 1
- initMockGraph(new long[] {1});
-
- // synchronize
- doSynchronization(sw);
-
- // check if single flow is installed
- assertEquals(1, idAdded.size());
- assertTrue(idAdded.contains((long)1));
- assertEquals(0, idRemoved.size());
- }
+ /**
+ * Test that synchronization doesn't affect anything in case either DB and
+ * flow table has the same entries.
+ */
+ @Test
+ public void testStable() {
+ // Create mock of flow table : flow 1
+ IOFSwitch sw = createMockSwitch(new long[]{1});
- /**
- * Test that an flow is deleted in case switch has an extra FlowEntry.
- */
- @Test
- public void testSingleDelete() {
- // Create mock of flow table : flow 1
- IOFSwitch sw = createMockSwitch(new long[] {1});
-
- // Create mock of flow entries : null
- initMockGraph(new long[] {});
-
- // synchronize
- doSynchronization(sw);
-
- // check if single flow is deleted
- assertEquals(0, idAdded.size());
- assertEquals(1, idRemoved.size());
- assertTrue(idRemoved.contains((long)1));
- }
-
- /**
- * Test that appropriate flows are added and other appropriate flows are deleted
- * in case flows in DB are overlapping flows in switch.
- */
- @Test
- public void testMixed() {
- // Create mock of flow table : flow 1,2,3
- IOFSwitch sw = createMockSwitch(new long[] {1,2,3});
-
- // Create mock of flow entries : flow 2,3,4,5
- initMockGraph(new long[] {2,3,4,5});
-
- // synchronize
- doSynchronization(sw);
-
- // check if two flows {4,5} is installed and one flow {1} is deleted
- assertEquals(2, idAdded.size());
- assertTrue(idAdded.contains((long)4));
- assertTrue(idAdded.contains((long)5));
- assertEquals(1, idRemoved.size());
- assertTrue(idRemoved.contains((long)1));
- }
-
+ // Create mock of flow entries : flow 1
+ initMockGraph(new long[]{1});
- @Test
- public void testMassive() {
- // Create mock of flow table : flow 0-1999
- long [] swIdList = new long [2000];
- for (long i = 0; i < 2000; ++i) {
- swIdList[(int)i] = i;
- }
- IOFSwitch sw = createMockSwitch(swIdList);
-
- // Create mock of flow entries : flow 1500-3499
- long [] dbIdList = new long [2000];
- for (long i = 0; i < 2000; ++i) {
- dbIdList[(int)i] = 1500 + i;
- }
- initMockGraph(dbIdList);
+ // synchronize
+ doSynchronization(sw);
- // synchronize
- doSynchronization(sw);
-
- // check if 1500 flows {2000-3499} is installed and 1500 flows {0,...,1499} is deleted
- assertEquals(1500, idAdded.size());
- for (long i = 2000; i < 3500; ++i) {
- assertTrue(idAdded.contains(i));
- }
- assertEquals(1500, idRemoved.size());
- for (long i = 0; i < 1500; ++i) {
- assertTrue(idRemoved.contains(i));
- }
- }
+ // check if flow is not changed
+ assertEquals(0, idAdded.size());
+ assertEquals(0, idRemoved.size());
+ }
- /**
- * Create mock IOFSwitch with flow table which has arbitrary flows.
- * @param cookieList List of FlowEntry IDs switch has.
- * @return Mock object.
- */
- private IOFSwitch createMockSwitch(long[] cookieList) {
- IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
- EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
-
- List<OFStatistics> stats = new ArrayList<OFStatistics>();
- for (long cookie : cookieList) {
- stats.add(createReply(cookie));
- }
-
- @SuppressWarnings("unchecked")
- Future<List<OFStatistics>> future = EasyMock.createMock(Future.class);
- try {
- EasyMock.expect(future.get()).andReturn(stats).once();
- } catch (InterruptedException e1) {
- fail("Failed in Future#get()");
- } catch (ExecutionException e1) {
- fail("Failed in Future#get()");
- }
- EasyMock.replay(future);
-
- try {
- EasyMock.expect(sw.getStatistics(EasyMock.anyObject(OFStatisticsRequest.class)))
- .andReturn(future).once();
- } catch (IOException e) {
- fail("Failed in IOFSwitch#getStatistics()");
- }
-
- EasyMock.replay(sw);
- return sw;
- }
-
- /**
- * Create single OFFlowStatisticsReply object which is actually obtained from switch.
- * @param cookie Cookie value, which indicates ID of FlowEntry installed to switch.
- * @return Created object.
- */
- private OFFlowStatisticsReply createReply(long cookie) {
- OFFlowStatisticsReply stat = new OFFlowStatisticsReply();
- OFMatch match = new OFMatch();
-
- stat.setCookie(cookie);
- stat.setMatch(match);
- stat.setPriority((short)1);
+ /**
+ * Test that an flow is added in case DB has an extra FlowEntry.
+ */
+ @Test
+ public void testSingleAdd() {
+ // Create mock of flow table : null
+ IOFSwitch sw = createMockSwitch(new long[]{});
- return stat;
- }
-
- /**
- * Create mock FlowDatabaseOperation to mock DB.
- * @param idList List of FlowEntry IDs stored in DB.
- */
- private void initMockGraph(long[] idList) {
- /*
- * TODO: The old FlowDatabaseOperation class is gone, so the method
- * below needs to be rewritten.
- */
- /*
- List<IFlowEntry> flowEntryList = new ArrayList<IFlowEntry>();
-
- for (long id : idList) {
- IFlowEntry entry = EasyMock.createMock(IFlowEntry.class);
- EasyMock.expect(entry.getFlowEntryId()).andReturn(String.valueOf(id)).anyTimes();
- EasyMock.replay(entry);
- flowEntryList.add(entry);
- }
-
- ISwitchObject swObj = EasyMock.createMock(ISwitchObject.class);
- EasyMock.expect(swObj.getFlowEntries()).andReturn(flowEntryList).once();
- EasyMock.replay(swObj);
-
- DBOperation mockOp = PowerMock.createMock(DBOperation.class);
- EasyMock.expect(mockOp.searchSwitch(EasyMock.anyObject(String.class))).andReturn(swObj).once();
-
- PowerMock.mockStatic(FlowDatabaseOperation.class);
- for (IFlowEntry entry : flowEntryList) {
- EasyMock.expect(FlowDatabaseOperation.extractFlowEntry(EasyMock.eq(entry)))
- .andAnswer(new IAnswer<FlowEntry>() {
- @Override
- public FlowEntry answer() throws Throwable {
- IFlowEntry iflow = (IFlowEntry)EasyMock.getCurrentArguments()[0];
- long flowEntryId = Long.valueOf(iflow.getFlowEntryId());
-
- FlowEntry flow = EasyMock.createMock(FlowEntry.class);
- EasyMock.expect(flow.flowEntryId()).andReturn(new FlowEntryId(flowEntryId)).anyTimes();
- EasyMock.replay(flow);
- return flow;
- }
-
- }).anyTimes();
- EasyMock.expect(mockOp.searchFlowEntry(EasyMock.eq(new FlowEntryId(entry.getFlowEntryId()))))
- .andReturn(entry);
- }
- PowerMock.replay(FlowDatabaseOperation.class);
- EasyMock.replay(mockOp);
-
- try {
- PowerMock.expectNew(DBOperation.class).andReturn(mockOp);
- } catch (Exception e) {
- fail("Failed to create DBOperation");
- }
- PowerMock.replay(DBOperation.class);
- */
- }
-
- /**
- * Instantiate FlowSynchronizer and sync flows.
- * @param sw Target IOFSwitch object
- */
- private void doSynchronization(IOFSwitch sw) {
- sync = new FlowSynchronizer();
- sync.init(pusher);
- Future<SyncResult> future = sync.synchronize(sw);
- try {
- future.get();
- } catch (Exception e) {
- fail("Failed to Future#get()");
- }
- }
+ // Create mock of flow entries : flow 1
+ initMockGraph(new long[]{1});
+
+ // synchronize
+ doSynchronization(sw);
+
+ // check if single flow is installed
+ assertEquals(1, idAdded.size());
+ assertTrue(idAdded.contains((long) 1));
+ assertEquals(0, idRemoved.size());
+ }
+
+ /**
+ * Test that an flow is deleted in case switch has an extra FlowEntry.
+ */
+ @Test
+ public void testSingleDelete() {
+ // Create mock of flow table : flow 1
+ IOFSwitch sw = createMockSwitch(new long[]{1});
+
+ // Create mock of flow entries : null
+ initMockGraph(new long[]{});
+
+ // synchronize
+ doSynchronization(sw);
+
+ // check if single flow is deleted
+ assertEquals(0, idAdded.size());
+ assertEquals(1, idRemoved.size());
+ assertTrue(idRemoved.contains((long) 1));
+ }
+
+ /**
+ * Test that appropriate flows are added and other appropriate flows are deleted
+ * in case flows in DB are overlapping flows in switch.
+ */
+ @Test
+ public void testMixed() {
+ // Create mock of flow table : flow 1,2,3
+ IOFSwitch sw = createMockSwitch(new long[]{1, 2, 3});
+
+ // Create mock of flow entries : flow 2,3,4,5
+ initMockGraph(new long[]{2, 3, 4, 5});
+
+ // synchronize
+ doSynchronization(sw);
+
+ // check if two flows {4,5} is installed and one flow {1} is deleted
+ assertEquals(2, idAdded.size());
+ assertTrue(idAdded.contains((long) 4));
+ assertTrue(idAdded.contains((long) 5));
+ assertEquals(1, idRemoved.size());
+ assertTrue(idRemoved.contains((long) 1));
+ }
+
+
+ @Test
+ public void testMassive() {
+ // Create mock of flow table : flow 0-1999
+ long[] swIdList = new long[2000];
+ for (long i = 0; i < 2000; ++i) {
+ swIdList[(int) i] = i;
+ }
+ IOFSwitch sw = createMockSwitch(swIdList);
+
+ // Create mock of flow entries : flow 1500-3499
+ long[] dbIdList = new long[2000];
+ for (long i = 0; i < 2000; ++i) {
+ dbIdList[(int) i] = 1500 + i;
+ }
+ initMockGraph(dbIdList);
+
+ // synchronize
+ doSynchronization(sw);
+
+ // check if 1500 flows {2000-3499} is installed and 1500 flows {0,...,1499} is deleted
+ assertEquals(1500, idAdded.size());
+ for (long i = 2000; i < 3500; ++i) {
+ assertTrue(idAdded.contains(i));
+ }
+ assertEquals(1500, idRemoved.size());
+ for (long i = 0; i < 1500; ++i) {
+ assertTrue(idRemoved.contains(i));
+ }
+ }
+
+ /**
+ * Create mock IOFSwitch with flow table which has arbitrary flows.
+ *
+ * @param cookieList List of FlowEntry IDs switch has.
+ * @return Mock object.
+ */
+ private IOFSwitch createMockSwitch(long[] cookieList) {
+ IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
+ EasyMock.expect(sw.getId()).andReturn((long) 1).anyTimes();
+
+ List<OFStatistics> stats = new ArrayList<OFStatistics>();
+ for (long cookie : cookieList) {
+ stats.add(createReply(cookie));
+ }
+
+ @SuppressWarnings("unchecked")
+ Future<List<OFStatistics>> future = EasyMock.createMock(Future.class);
+ try {
+ EasyMock.expect(future.get()).andReturn(stats).once();
+ } catch (InterruptedException e1) {
+ fail("Failed in Future#get()");
+ } catch (ExecutionException e1) {
+ fail("Failed in Future#get()");
+ }
+ EasyMock.replay(future);
+
+ try {
+ EasyMock.expect(sw.getStatistics(EasyMock.anyObject(OFStatisticsRequest.class)))
+ .andReturn(future).once();
+ } catch (IOException e) {
+ fail("Failed in IOFSwitch#getStatistics()");
+ }
+
+ EasyMock.replay(sw);
+ return sw;
+ }
+
+ /**
+ * Create single OFFlowStatisticsReply object which is actually obtained from switch.
+ *
+ * @param cookie Cookie value, which indicates ID of FlowEntry installed to switch.
+ * @return Created object.
+ */
+ private OFFlowStatisticsReply createReply(long cookie) {
+ OFFlowStatisticsReply stat = new OFFlowStatisticsReply();
+ OFMatch match = new OFMatch();
+
+ stat.setCookie(cookie);
+ stat.setMatch(match);
+ stat.setPriority((short) 1);
+
+ return stat;
+ }
+
+ /**
+ * Create mock FlowDatabaseOperation to mock DB.
+ *
+ * @param idList List of FlowEntry IDs stored in DB.
+ */
+ private void initMockGraph(long[] idList) {
+ /*
+ * TODO: The old FlowDatabaseOperation class is gone, so the method
+ * below needs to be rewritten.
+ */
+ /*
+ List<IFlowEntry> flowEntryList = new ArrayList<IFlowEntry>();
+
+ for (long id : idList) {
+ IFlowEntry entry = EasyMock.createMock(IFlowEntry.class);
+ EasyMock.expect(entry.getFlowEntryId()).andReturn(String.valueOf(id)).anyTimes();
+ EasyMock.replay(entry);
+ flowEntryList.add(entry);
+ }
+
+ ISwitchObject swObj = EasyMock.createMock(ISwitchObject.class);
+ EasyMock.expect(swObj.getFlowEntries()).andReturn(flowEntryList).once();
+ EasyMock.replay(swObj);
+
+ DBOperation mockOp = PowerMock.createMock(DBOperation.class);
+ EasyMock.expect(mockOp.searchSwitch(EasyMock.anyObject(String.class))).andReturn(swObj).once();
+
+ PowerMock.mockStatic(FlowDatabaseOperation.class);
+ for (IFlowEntry entry : flowEntryList) {
+ EasyMock.expect(FlowDatabaseOperation.extractFlowEntry(EasyMock.eq(entry)))
+ .andAnswer(new IAnswer<FlowEntry>() {
+ @Override
+ public FlowEntry answer() throws Throwable {
+ IFlowEntry iflow = (IFlowEntry)EasyMock.getCurrentArguments()[0];
+ long flowEntryId = Long.valueOf(iflow.getFlowEntryId());
+
+ FlowEntry flow = EasyMock.createMock(FlowEntry.class);
+ EasyMock.expect(flow.flowEntryId()).andReturn(new FlowEntryId(flowEntryId)).anyTimes();
+ EasyMock.replay(flow);
+ return flow;
+ }
+
+ }).anyTimes();
+ EasyMock.expect(mockOp.searchFlowEntry(EasyMock.eq(new FlowEntryId(entry.getFlowEntryId()))))
+ .andReturn(entry);
+ }
+ PowerMock.replay(FlowDatabaseOperation.class);
+ EasyMock.replay(mockOp);
+
+ try {
+ PowerMock.expectNew(DBOperation.class).andReturn(mockOp);
+ } catch (Exception e) {
+ fail("Failed to create DBOperation");
+ }
+ PowerMock.replay(DBOperation.class);
+ */
+ }
+
+ /**
+ * Instantiate FlowSynchronizer and sync flows.
+ *
+ * @param sw Target IOFSwitch object
+ */
+ private void doSynchronization(IOFSwitch sw) {
+ sync = new FlowSynchronizer();
+ sync.init(pusher);
+ Future<SyncResult> future = sync.synchronize(sw);
+ try {
+ future.get();
+ } catch (Exception e) {
+ fail("Failed to Future#get()");
+ }
+ }
}