Renamed devicemanager, flowprogrammer, linkdiscovery and util packages
net.onrc.onos.ofcontroller.devicemanager.* => net.onrc.onos.core.devicemanager.*
net.onrc.onos.ofcontroller.flowprogrammer.* => net.onrc.onos.core.flowprogrammer.*
net.onrc.onos.ofcontroller.linkdiscovery.* => net.onrc.onos.core.linkdiscovery.*
net.onrc.onos.ofcontroller.util.* => net.onrc.onos.core.util.*
Change-Id: Iaa865af552e8fb3a589e73d006569ac79f5a0f08
diff --git a/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java
new file mode 100644
index 0000000..5708442
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java
@@ -0,0 +1,555 @@
+package net.onrc.onos.core.flowprogrammer;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import net.floodlightcontroller.core.FloodlightContext;
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.floodlightcontroller.util.OFMessageDamper;
+import net.onrc.onos.core.flowprogrammer.FlowPusher;
+import net.onrc.onos.core.flowprogrammer.OFBarrierReplyFuture;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.FlowEntry;
+import net.onrc.onos.core.util.FlowEntryActions;
+import net.onrc.onos.core.util.FlowEntryErrorState;
+import net.onrc.onos.core.util.FlowEntryId;
+import net.onrc.onos.core.util.FlowEntryMatch;
+import net.onrc.onos.core.util.FlowEntryUserState;
+import net.onrc.onos.core.util.FlowId;
+import net.onrc.onos.core.util.Port;
+
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.Test;
+import org.openflow.protocol.OFBarrierReply;
+import org.openflow.protocol.OFBarrierRequest;
+import org.openflow.protocol.OFFlowMod;
+import org.openflow.protocol.OFMatch;
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFType;
+import org.openflow.protocol.action.OFAction;
+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;
+
+ /**
+ * 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();
+
+ 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();
+
+ 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
new file mode 100644
index 0000000..13d5a87
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizerTest.java
@@ -0,0 +1,324 @@
+package net.onrc.onos.core.flowprogrammer;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import net.floodlightcontroller.core.IOFSwitch;
+import net.onrc.onos.core.flowprogrammer.FlowPusher;
+import net.onrc.onos.core.flowprogrammer.FlowSynchronizer;
+import net.onrc.onos.core.flowprogrammer.IFlowPusherService.MsgPriority;
+import net.onrc.onos.core.flowprogrammer.IFlowSyncService.SyncResult;
+import net.onrc.onos.core.util.FlowEntry;
+import net.onrc.onos.core.util.FlowEntryId;
+
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.protocol.OFFlowMod;
+import org.openflow.protocol.OFMatch;
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFStatisticsRequest;
+import org.openflow.protocol.OFType;
+import org.openflow.protocol.statistics.OFFlowStatisticsReply;
+import org.openflow.protocol.statistics.OFStatistics;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+// Test should be fixed to fit RAMCloud basis
+@Ignore
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({FlowSynchronizer.class})
+public class FlowSynchronizerTest {
+ 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);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ /**
+ * 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());
+ }
+
+ /**
+ * 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 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()");
+ }
+ }
+}
diff --git a/src/test/java/net/onrc/onos/core/intent/ConstrainedShortestPathIntentTest.java b/src/test/java/net/onrc/onos/core/intent/ConstrainedShortestPathIntentTest.java
index b0a8afc..e3dae31 100644
--- a/src/test/java/net/onrc/onos/core/intent/ConstrainedShortestPathIntentTest.java
+++ b/src/test/java/net/onrc/onos/core/intent/ConstrainedShortestPathIntentTest.java
@@ -2,7 +2,7 @@
import static org.junit.Assert.assertEquals;
import net.onrc.onos.core.intent.ConstrainedShortestPathIntent;
-import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
+import net.onrc.onos.core.util.serializers.KryoFactory;
import org.junit.After;
import org.junit.Before;
diff --git a/src/test/java/net/onrc/onos/core/intent/IntentOperationListTest.java b/src/test/java/net/onrc/onos/core/intent/IntentOperationListTest.java
index aa1410d..aa87cbd 100644
--- a/src/test/java/net/onrc/onos/core/intent/IntentOperationListTest.java
+++ b/src/test/java/net/onrc/onos/core/intent/IntentOperationListTest.java
@@ -6,9 +6,9 @@
import net.onrc.onos.core.intent.IntentOperation;
import net.onrc.onos.core.intent.IntentOperationList;
import net.onrc.onos.core.intent.PathIntent;
+import net.onrc.onos.core.util.serializers.KryoFactory;
import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
import net.onrc.onos.ofcontroller.networkgraph.Path;
-import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
import org.junit.After;
import org.junit.Before;
diff --git a/src/test/java/net/onrc/onos/core/intent/PathIntentTest.java b/src/test/java/net/onrc/onos/core/intent/PathIntentTest.java
index 9b4b255..520d87d 100644
--- a/src/test/java/net/onrc/onos/core/intent/PathIntentTest.java
+++ b/src/test/java/net/onrc/onos/core/intent/PathIntentTest.java
@@ -3,9 +3,9 @@
import static org.junit.Assert.assertEquals;
import net.onrc.onos.core.intent.ConstrainedShortestPathIntent;
import net.onrc.onos.core.intent.PathIntent;
+import net.onrc.onos.core.util.serializers.KryoFactory;
import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
import net.onrc.onos.ofcontroller.networkgraph.Path;
-import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
import org.junit.After;
import org.junit.Before;
diff --git a/src/test/java/net/onrc/onos/core/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/onrc/onos/core/linkdiscovery/internal/LinkDiscoveryManagerTest.java
new file mode 100644
index 0000000..a05d9c6
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/linkdiscovery/internal/LinkDiscoveryManagerTest.java
@@ -0,0 +1,383 @@
+/**
+* Copyright 2011, Big Switch Networks, Inc.
+* Originally created by David Erickson, Stanford University
+*
+* Licensed under the Apache License, Version 2.0 (the "License"); you may
+* not use this file except in compliance with the License. You may obtain
+* a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+**/
+
+package net.onrc.onos.core.linkdiscovery.internal;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.test.MockThreadPoolService;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.restserver.RestApiServer;
+import net.floodlightcontroller.test.FloodlightTestCase;
+import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryListener;
+import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.core.linkdiscovery.Link;
+import net.onrc.onos.core.linkdiscovery.LinkInfo;
+import net.onrc.onos.core.linkdiscovery.NodePortTuple;
+import net.onrc.onos.core.linkdiscovery.internal.LinkDiscoveryManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class LinkDiscoveryManagerTest extends FloodlightTestCase {
+
+ private TestLinkDiscoveryManager ldm;
+ protected final static Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
+
+ public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
+ public boolean isSendLLDPsCalled = false;
+ public boolean isClearLinksCalled = false;
+
+ @Override
+ protected void discoverOnAllPorts() {
+ isSendLLDPsCalled = true;
+ super.discoverOnAllPorts();
+ }
+
+ public void reset() {
+ isSendLLDPsCalled = false;
+ isClearLinksCalled = false;
+ }
+ }
+
+ public LinkDiscoveryManager getTopology() {
+ return ldm;
+ }
+
+ public IOFSwitch createMockSwitch(Long id) {
+ IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
+ expect(mockSwitch.getId()).andReturn(id).anyTimes();
+ return mockSwitch;
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ FloodlightModuleContext cntx = new FloodlightModuleContext();
+ ldm = new TestLinkDiscoveryManager();
+ ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
+ MockThreadPoolService tp = new MockThreadPoolService();
+ RestApiServer restApi = new RestApiServer();
+ cntx.addService(IRestApiService.class, restApi);
+ cntx.addService(IThreadPoolService.class, tp);
+ cntx.addService(ILinkDiscoveryService.class, ldm);
+ cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
+ restApi.init(cntx);
+ tp.init(cntx);
+ ldm.init(cntx);
+ restApi.startUp(cntx);
+ tp.startUp(cntx);
+ ldm.startUp(cntx);
+
+ IOFSwitch sw1 = createMockSwitch(1L);
+ IOFSwitch sw2 = createMockSwitch(2L);
+ Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
+ switches.put(1L, sw1);
+ switches.put(2L, sw2);
+ getMockFloodlightProvider().setSwitches(switches);
+ replay(sw1, sw2);
+ }
+
+ @Test
+ public void testAddOrUpdateLink() throws Exception {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 2, 2L, 1);
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+
+
+ NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+ NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+
+ // check invariants hold
+ assertNotNull(topology.switchLinks.get(lt.getSrc()));
+ assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
+ assertNotNull(topology.portLinks.get(srcNpt));
+ assertTrue(topology.portLinks.get(srcNpt).contains(lt));
+ assertNotNull(topology.portLinks.get(dstNpt));
+ assertTrue(topology.portLinks.get(dstNpt).contains(lt));
+ assertTrue(topology.links.containsKey(lt));
+ }
+
+ @Test
+ public void testDeleteLink() throws Exception {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 2, 2L, 1);
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ topology.deleteLinks(Collections.singletonList(lt), "Test");
+
+ // check invariants hold
+ assertNull(topology.switchLinks.get(lt.getSrc()));
+ assertNull(topology.switchLinks.get(lt.getDst()));
+ assertNull(topology.portLinks.get(lt.getSrc()));
+ assertNull(topology.portLinks.get(lt.getDst()));
+ assertTrue(topology.links.isEmpty());
+ }
+
+ @Test
+ public void testAddOrUpdateLinkToSelf() throws Exception {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 2, 2L, 3);
+ NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+ NodePortTuple dstNpt = new NodePortTuple(2L, 3);
+
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+
+ // check invariants hold
+ assertNotNull(topology.switchLinks.get(lt.getSrc()));
+ assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
+ assertNotNull(topology.portLinks.get(srcNpt));
+ assertTrue(topology.portLinks.get(srcNpt).contains(lt));
+ assertNotNull(topology.portLinks.get(dstNpt));
+ assertTrue(topology.portLinks.get(dstNpt).contains(lt));
+ assertTrue(topology.links.containsKey(lt));
+ }
+
+ @Test
+ public void testDeleteLinkToSelf() throws Exception {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 2, 1L, 3);
+ NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+ NodePortTuple dstNpt = new NodePortTuple(2L, 3);
+
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ topology.deleteLinks(Collections.singletonList(lt), "Test to self");
+
+ // check invariants hold
+ assertNull(topology.switchLinks.get(lt.getSrc()));
+ assertNull(topology.switchLinks.get(lt.getDst()));
+ assertNull(topology.portLinks.get(srcNpt));
+ assertNull(topology.portLinks.get(dstNpt));
+ assertTrue(topology.links.isEmpty());
+ }
+
+ @Test
+ public void testRemovedSwitch() {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 2, 2L, 1);
+ NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+ NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+
+ IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
+ IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
+ // Mock up our expected behavior
+ topology.removedSwitch(sw1);
+ verify(sw1, sw2);
+
+ // check invariants hold
+ assertNull(topology.switchLinks.get(lt.getSrc()));
+ assertNull(topology.switchLinks.get(lt.getDst()));
+ assertNull(topology.portLinks.get(srcNpt));
+ assertNull(topology.portLinks.get(dstNpt));
+ assertTrue(topology.links.isEmpty());
+ }
+
+ @Test
+ public void testRemovedSwitchSelf() {
+ LinkDiscoveryManager topology = getTopology();
+ IOFSwitch sw1 = createMockSwitch(1L);
+ replay(sw1);
+ Link lt = new Link(1L, 2, 1L, 3);
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+
+ // Mock up our expected behavior
+ topology.removedSwitch(sw1);
+
+ verify(sw1);
+ // check invariants hold
+ assertNull(topology.switchLinks.get(lt.getSrc()));
+ assertNull(topology.portLinks.get(lt.getSrc()));
+ assertNull(topology.portLinks.get(lt.getDst()));
+ assertTrue(topology.links.isEmpty());
+ }
+
+ @Test
+ public void testAddUpdateLinks() throws Exception {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 1, 2L, 1);
+ NodePortTuple srcNpt = new NodePortTuple(1L, 1);
+ NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+
+ LinkInfo info;
+
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ System.currentTimeMillis() - 40000, null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+
+ // check invariants hold
+ assertNotNull(topology.switchLinks.get(lt.getSrc()));
+ assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
+ assertNotNull(topology.portLinks.get(srcNpt));
+ assertTrue(topology.portLinks.get(srcNpt).contains(lt));
+ assertNotNull(topology.portLinks.get(dstNpt));
+ assertTrue(topology.portLinks.get(dstNpt).contains(lt));
+ assertTrue(topology.links.containsKey(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+ topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+ topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+ topology.timeoutLinks();
+
+
+ info = new LinkInfo(System.currentTimeMillis(),/* firstseen */
+ null,/* unicast */
+ System.currentTimeMillis(), 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
+ assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+ // Add a link info based on info that woudld be obtained from unicast LLDP
+ // Setting the unicast LLDP reception time to be 40 seconds old, so we can use
+ // this to test timeout after this test. Although the info is initialized
+ // with LT_OPENFLOW_LINK, the link property should be changed to LT_NON_OPENFLOW
+ // by the addOrUpdateLink method.
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ System.currentTimeMillis() - 40000, null, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+ topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+ topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+ // Expect to timeout the unicast Valid Time, but not the multicast Valid time
+ // So the link type should go back to non-openflow link.
+ topology.timeoutLinks();
+ assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
+ assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+ // Set the multicastValidTime to be old and see if that also times out.
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ topology.timeoutLinks();
+ assertTrue(topology.links.get(lt) == null);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+ topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+ topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+
+ // Test again only with multicast LLDP
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
+ assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+ // Call timeout and check if link is no longer present.
+ topology.timeoutLinks();
+ assertTrue(topology.links.get(lt) == null);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+ topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+ topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+ // Start clean and see if loops are also added.
+ lt = new Link(1L, 1, 1L, 2);
+ srcNpt = new NodePortTuple(1L, 1);
+ dstNpt = new NodePortTuple(1L, 2);
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+ // Start clean and see if loops are also added.
+ lt = new Link(1L, 1, 1L, 3);
+ srcNpt = new NodePortTuple(1L, 1);
+ dstNpt = new NodePortTuple(1L, 3);
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+ // Start clean and see if loops are also added.
+ lt = new Link(1L, 4, 1L, 5);
+ srcNpt = new NodePortTuple(1L, 4);
+ dstNpt = new NodePortTuple(1L, 5);
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+ // Start clean and see if loops are also added.
+ lt = new Link(1L, 3, 1L, 5);
+ srcNpt = new NodePortTuple(1L, 3);
+ dstNpt = new NodePortTuple(1L, 5);
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+ }
+}
diff --git a/src/test/java/net/onrc/onos/core/util/FlowEntryActionTest.java b/src/test/java/net/onrc/onos/core/util/FlowEntryActionTest.java
new file mode 100644
index 0000000..e80c803
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/util/FlowEntryActionTest.java
@@ -0,0 +1,430 @@
+package net.onrc.onos.core.util;
+
+import static org.junit.Assert.assertEquals;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.util.FlowEntryAction;
+import net.onrc.onos.core.util.IPv4;
+import net.onrc.onos.core.util.Port;
+import net.onrc.onos.core.util.FlowEntryAction.ActionEnqueue;
+import net.onrc.onos.core.util.FlowEntryAction.ActionOutput;
+import net.onrc.onos.core.util.FlowEntryAction.ActionSetEthernetAddr;
+import net.onrc.onos.core.util.FlowEntryAction.ActionSetIPv4Addr;
+import net.onrc.onos.core.util.FlowEntryAction.ActionSetIpToS;
+import net.onrc.onos.core.util.FlowEntryAction.ActionSetTcpUdpPort;
+import net.onrc.onos.core.util.FlowEntryAction.ActionSetVlanId;
+import net.onrc.onos.core.util.FlowEntryAction.ActionSetVlanPriority;
+import net.onrc.onos.core.util.FlowEntryAction.ActionStripVlan;
+
+import org.junit.Test;
+
+public class FlowEntryActionTest {
+
+ @Test
+ public void testSetActionOutputActionOutput(){
+ FlowEntryAction act = new FlowEntryAction();
+ ActionOutput actout = new FlowEntryAction.ActionOutput(new Port((short)42));
+ act.setActionOutput(actout);
+
+ assertEquals("action output",FlowEntryAction.ActionValues.ACTION_OUTPUT , act.actionType());
+ assertEquals("actionOutput port should be the same", actout.port(), act.actionOutput().port());
+ assertEquals("actionOutput maxlen should be the same", actout.maxLen(), act.actionOutput().maxLen());
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionOutputPort(){
+ FlowEntryAction act = new FlowEntryAction();
+ act.setActionOutput(new Port((short)42));
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionOutputToController(){
+ FlowEntryAction act = new FlowEntryAction();
+ act.setActionOutputToController((short)0);
+
+ FlowEntryAction act_copy = new FlowEntryAction();
+ act_copy.setActionOutput(new Port(Port.PortValues.PORT_CONTROLLER));
+ ;
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetVlanIdActionSetVlanId(){
+ FlowEntryAction act = new FlowEntryAction();
+ ActionSetVlanId actVlan = new FlowEntryAction.ActionSetVlanId((short)42);
+ act.setActionSetVlanId(actVlan);
+
+ assertEquals("action type",FlowEntryAction.ActionValues.ACTION_SET_VLAN_VID , act.actionType());
+ assertEquals("vlanid should be the same", actVlan.vlanId(), act.actionSetVlanId().vlanId());
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetVlanIdShort(){
+ FlowEntryAction act = new FlowEntryAction();
+ act.setActionSetVlanId((short)42);
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetVlanPriorityActionSetVlanPriority(){
+ FlowEntryAction act = new FlowEntryAction();
+ ActionSetVlanPriority actVlan = new FlowEntryAction.ActionSetVlanPriority((byte)42);
+ act.setActionSetVlanPriority(actVlan);
+
+ assertEquals("action type",FlowEntryAction.ActionValues.ACTION_SET_VLAN_PCP , act.actionType());
+ assertEquals("vlan priority should be the same", actVlan.vlanPriority(), act.actionSetVlanPriority().vlanPriority());
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetVlanPriorityByte(){
+ FlowEntryAction act = new FlowEntryAction();
+ act.setActionSetVlanPriority((byte)42);
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionStripVlanActionStripVlan(){
+ FlowEntryAction act = new FlowEntryAction();
+ ActionStripVlan actVlan = new FlowEntryAction.ActionStripVlan();
+ act.setActionStripVlan(actVlan);
+
+ assertEquals("action type",FlowEntryAction.ActionValues.ACTION_STRIP_VLAN , act.actionType());
+ assertEquals("vlanid should be the same", actVlan.stripVlan(), act.actionStripVlan().stripVlan());
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionStripVlanBoolean(){
+ FlowEntryAction act = new FlowEntryAction();
+ act.setActionStripVlan(true);
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetEthernetSrcAddrActionSetEthernetAddr(){
+ FlowEntryAction act = new FlowEntryAction();
+ byte[] mac = { 1, 2, 3, 4, 5, 6 };
+ ActionSetEthernetAddr setEth = new FlowEntryAction.ActionSetEthernetAddr(new MACAddress(mac));
+ act.setActionSetEthernetSrcAddr( setEth );
+
+ assertEquals("action type",FlowEntryAction.ActionValues.ACTION_SET_DL_SRC , act.actionType());
+ assertEquals("addr should be the same", setEth.addr(), act.actionSetEthernetSrcAddr().addr());
+
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetEthernetSrcAddrMACAddress(){
+ FlowEntryAction act = new FlowEntryAction();
+ byte[] mac = { 1, 2, 3, 4, 5, 6 };
+ act.setActionSetEthernetSrcAddr(new MACAddress(mac));
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetEthernetDstAddrActionSetEthernetAddr(){
+ FlowEntryAction act = new FlowEntryAction();
+ byte[] mac = { 1, 2, 3, 4, 5, 6 };
+ ActionSetEthernetAddr setEth = new FlowEntryAction.ActionSetEthernetAddr(new MACAddress(mac));
+ act.setActionSetEthernetDstAddr( setEth );
+
+ assertEquals("action type",FlowEntryAction.ActionValues.ACTION_SET_DL_DST , act.actionType());
+ assertEquals("addr should be the same", setEth.addr(), act.actionSetEthernetDstAddr().addr());
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetEthernetDstAddrMACAddress(){
+ FlowEntryAction act = new FlowEntryAction();
+ byte[] mac = { 1, 2, 3, 4, 5, 6 };
+ act.setActionSetEthernetDstAddr(new MACAddress(mac));
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetIPv4SrcAddrActionSetIPv4Addr(){
+ FlowEntryAction act = new FlowEntryAction();
+ ActionSetIPv4Addr setIp = new FlowEntryAction.ActionSetIPv4Addr(new IPv4("127.0.0.1"));
+ act.setActionSetIPv4SrcAddr( setIp );
+
+ assertEquals("action type",FlowEntryAction.ActionValues.ACTION_SET_NW_SRC , act.actionType());
+ assertEquals("addr should be the same", setIp.addr(), act.actionSetIPv4SrcAddr().addr());
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetIPv4SrcAddrIPv4(){
+ FlowEntryAction act = new FlowEntryAction();
+ act.setActionSetIPv4SrcAddr(new IPv4("127.0.0.1"));
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetIPv4DstAddrActionSetIPv4Addr(){
+ FlowEntryAction act = new FlowEntryAction();
+ ActionSetIPv4Addr setIp = new FlowEntryAction.ActionSetIPv4Addr(new IPv4("127.0.0.1"));
+ act.setActionSetIPv4DstAddr( setIp );
+
+ assertEquals("action type",FlowEntryAction.ActionValues.ACTION_SET_NW_DST , act.actionType());
+ assertEquals("addr should be the same", setIp.addr(), act.actionSetIPv4DstAddr().addr());
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetIPv4DstAddrIPv4(){
+ FlowEntryAction act = new FlowEntryAction();
+ act.setActionSetIPv4DstAddr(new IPv4("127.0.0.1"));
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetIpToSActionSetIpToS(){
+ FlowEntryAction act = new FlowEntryAction();
+ ActionSetIpToS setIpTos = new FlowEntryAction.ActionSetIpToS((byte)42);
+ act.setActionSetIpToS( setIpTos );
+
+ assertEquals("action type",FlowEntryAction.ActionValues.ACTION_SET_NW_TOS , act.actionType());
+ assertEquals("tos should be the same", setIpTos.ipToS(), act.actionSetIpToS().ipToS());
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetIpToSByte(){
+ FlowEntryAction act = new FlowEntryAction();
+ act.setActionSetIpToS((byte)1);
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetTcpUdpSrcPortActionSetTcpUdpPort(){
+ FlowEntryAction act = new FlowEntryAction();
+ ActionSetTcpUdpPort setPorts = new FlowEntryAction.ActionSetTcpUdpPort((short)42);
+ act.setActionSetTcpUdpSrcPort( setPorts );
+
+ assertEquals("action type",FlowEntryAction.ActionValues.ACTION_SET_TP_SRC , act.actionType());
+ assertEquals("port should be the same", setPorts.port(), act.actionSetTcpUdpSrcPort().port());
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetTcpUdpSrcPortShort(){
+ FlowEntryAction act = new FlowEntryAction();
+ act.setActionSetTcpUdpSrcPort((short)1);
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetTcpUdpDstPortActionSetTcpUdpPort(){
+ FlowEntryAction act = new FlowEntryAction();
+ ActionSetTcpUdpPort setPorts = new FlowEntryAction.ActionSetTcpUdpPort((short)42);
+ act.setActionSetTcpUdpDstPort( setPorts );
+
+ assertEquals("action type",FlowEntryAction.ActionValues.ACTION_SET_TP_DST , act.actionType());
+ assertEquals("port should be the same", setPorts.port(), act.actionSetTcpUdpDstPort().port());
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionSetTcpUdpDstPortShort(){
+ FlowEntryAction act = new FlowEntryAction();
+ act.setActionSetTcpUdpDstPort((short)1);
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionEnqueueActionEnqueue(){
+ FlowEntryAction act = new FlowEntryAction();
+ ActionEnqueue enq = new FlowEntryAction.ActionEnqueue(new Port((short)42), 1);
+ act.setActionEnqueue( enq );
+
+ assertEquals("action type",FlowEntryAction.ActionValues.ACTION_ENQUEUE , act.actionType());
+ assertEquals("port should be the same", enq.port(), act.actionEnqueue().port());
+ assertEquals("queue id should be the same", enq.queueId(), act.actionEnqueue().queueId());
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+ @Test
+ public void testSetActionEnqueuePortInt(){
+ FlowEntryAction act = new FlowEntryAction();
+ act.setActionEnqueue(new Port((short)42), 1);
+
+ FlowEntryAction act_copy = new FlowEntryAction(act);
+ FlowEntryAction act_copy2 = new FlowEntryAction(act.toString());
+
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy.toString());
+ assertEquals("toString must match between copies", act.toString(),
+ act_copy2.toString());
+ }
+
+}
diff --git a/src/test/java/net/onrc/onos/core/util/FlowEntryMatchTest.java b/src/test/java/net/onrc/onos/core/util/FlowEntryMatchTest.java
new file mode 100644
index 0000000..35c1be0
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/util/FlowEntryMatchTest.java
@@ -0,0 +1,315 @@
+package net.onrc.onos.core.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.util.FlowEntryMatch;
+import net.onrc.onos.core.util.IPv4Net;
+import net.onrc.onos.core.util.Port;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class FlowEntryMatchTest {
+
+ FlowEntryMatch match;
+
+ Port inport = new Port((short)1);
+ byte[] byte1 = { 1, 2, 3, 4, 5, 6 };
+ byte[] byte2 = { 6, 5, 4, 3, 2, 1 };
+ MACAddress mac1 = new MACAddress(byte1);
+ MACAddress mac2 = new MACAddress(byte2);
+ Short ether = Short.valueOf((short)2);
+ Short vlanid = Short.valueOf((short)3);
+ Byte vlanprio = Byte.valueOf((byte)4);
+ IPv4Net ip1 = new IPv4Net("127.0.0.1/32");
+ IPv4Net ip2 = new IPv4Net("127.0.0.2/32");
+ Byte ipproto = Byte.valueOf((byte)5);
+ Byte ipToS = Byte.valueOf((byte)6);
+ Short tport1 = Short.valueOf((short)7);
+ Short tport2 = Short.valueOf((short)8);
+
+ @Before
+ public void setUp() throws Exception{
+ match = new FlowEntryMatch();
+ match.enableInPort( inport);
+ match.enableSrcMac( mac1 );
+ match.enableDstMac( mac2 );
+ match.enableEthernetFrameType( ether );
+ match.enableVlanId( vlanid );
+ match.enableVlanPriority( vlanprio );
+ match.enableSrcIPv4Net( ip1 );
+ match.enableDstIPv4Net( ip2 );
+ match.enableIpProto( ipproto );
+ match.enableIpToS( ipToS );
+ match.enableSrcTcpUdpPort( tport1 );
+ match.enableDstTcpUdpPort( tport2 );
+ }
+
+ @Test
+ public void testFlowEntryMatch(){
+ FlowEntryMatch def = new FlowEntryMatch();
+
+ assertEquals("default null", null, def.inPort() );
+ assertEquals("default null", null, def.srcMac() );
+ assertEquals("default null", null, def.dstMac() );
+ assertEquals("default null", null, def.ethernetFrameType() );
+ assertEquals("default null", null, def.vlanId() );
+ assertEquals("default null", null, def.vlanPriority() );
+ assertEquals("default null", null, def.srcIPv4Net() );
+ assertEquals("default null", null, def.dstIPv4Net() );
+ assertEquals("default null", null, def.ipProto() );
+ assertEquals("default null", null, def.ipToS() );
+ assertEquals("default null", null, def.srcTcpUdpPort() );
+ assertEquals("default null", null, def.dstTcpUdpPort() );
+ }
+
+ @Test
+ public void testFlowEntryMatchFlowEntryMatch(){
+ FlowEntryMatch def_base = new FlowEntryMatch();
+ FlowEntryMatch def = new FlowEntryMatch(def_base);
+
+ assertEquals("default null", null, def.inPort() );
+ assertEquals("default null", null, def.srcMac() );
+ assertEquals("default null", null, def.dstMac() );
+ assertEquals("default null", null, def.ethernetFrameType() );
+ assertEquals("default null", null, def.vlanId() );
+ assertEquals("default null", null, def.vlanPriority() );
+ assertEquals("default null", null, def.srcIPv4Net() );
+ assertEquals("default null", null, def.dstIPv4Net() );
+ assertEquals("default null", null, def.ipProto() );
+ assertEquals("default null", null, def.ipToS() );
+ assertEquals("default null", null, def.srcTcpUdpPort() );
+ assertEquals("default null", null, def.dstTcpUdpPort() );
+
+ FlowEntryMatch copy = new FlowEntryMatch( match );
+
+ assertEquals("inport", inport, copy.inPort() );
+ assertEquals("mac1", mac1, copy.srcMac() );
+ assertEquals("mac2", mac2, copy.dstMac() );
+ assertEquals("ether", ether, copy.ethernetFrameType() );
+ assertEquals("vlan id", vlanid, copy.vlanId() );
+ assertEquals("vlan prio", vlanprio, copy.vlanPriority() );
+ assertEquals("ip1", ip1, copy.srcIPv4Net() );
+ assertEquals("ip2", ip2, copy.dstIPv4Net() );
+ assertEquals("ip proto", ipproto, copy.ipProto() );
+ assertEquals("tos", ipToS, copy.ipToS() );
+ assertEquals("src port", tport1, copy.srcTcpUdpPort() );
+ assertEquals("dst port", tport2, copy.dstTcpUdpPort() );
+
+ }
+
+ @Test
+ public void testInPort(){
+ assertEquals("inport", inport, match.inPort() );
+ }
+
+ @Test
+ public void testDisableInPort(){
+ match.disableInPort();
+ assertEquals("inport", null, match.inPort() );
+ assertFalse( match.matchInPort() );
+ }
+
+ @Test
+ public void testMatchInPort(){
+ assertTrue( match.matchInPort() );
+ }
+
+ @Test
+ public void testSrcMac(){
+ assertEquals("mac1", mac1, match.srcMac() );
+ }
+
+ @Test
+ public void testDisableSrcMac(){
+ match.disableSrcMac();
+ assertEquals("srcMac", null, match.srcMac() );
+ assertFalse( match.matchSrcMac() );
+ }
+
+ @Test
+ public void testMatchSrcMac(){
+ assertTrue( match.matchSrcMac() );
+ }
+
+ @Test
+ public void testDstMac(){
+ assertEquals("mac2", mac2, match.dstMac() );
+ }
+
+ @Test
+ public void testDisableDstMac(){
+ match.disableDstMac();
+ assertEquals("dstMac", null, match.dstMac() );
+ assertFalse( match.matchDstMac() );
+ }
+
+ @Test
+ public void testMatchDstMac(){
+ assertTrue( match.matchDstMac() );
+ }
+
+ @Test
+ public void testEthernetFrameType(){
+ assertEquals("ether", ether, match.ethernetFrameType() );
+ }
+
+ @Test
+ public void testDisableEthernetFrameType(){
+ match.disableEthernetFrameType();
+ assertEquals("ethernetFrameType", null, match.ethernetFrameType() );
+ assertFalse( match.matchEthernetFrameType() );
+ }
+
+ @Test
+ public void testMatchEthernetFrameType(){
+ assertTrue( match.matchEthernetFrameType() );
+ }
+
+ @Test
+ public void testVlanId(){
+ assertEquals("vlan id", vlanid, match.vlanId() );
+ }
+
+ @Test
+ public void testDisableVlanId(){
+ match.disableVlanId();
+ assertEquals("vlanId", null, match.vlanId() );
+ assertFalse( match.matchVlanId() );
+ }
+
+ @Test
+ public void testMatchVlanId(){
+ assertTrue( match.matchVlanId() );
+ }
+
+ @Test
+ public void testVlanPriority(){
+ assertEquals("vlan prio", vlanprio, match.vlanPriority() );
+ }
+
+ @Test
+ public void testDisableVlanPriority(){
+ match.disableVlanPriority();
+ assertEquals("vlanPriority", null, match.vlanPriority() );
+ assertFalse( match.matchVlanPriority() );
+ }
+
+ @Test
+ public void testMatchVlanPriority(){
+ assertTrue( match.matchVlanPriority() );
+ }
+
+ @Test
+ public void testSrcIPv4Net(){
+ assertEquals("ip1", ip1, match.srcIPv4Net() );
+ }
+
+ @Test
+ public void testDisableSrcIPv4Net(){
+ match.disableSrcIPv4Net();
+ assertEquals("srcIPv4Net", null, match.srcIPv4Net() );
+ assertFalse( match.matchSrcIPv4Net() );
+ }
+
+ @Test
+ public void testMatchSrcIPv4Net(){
+ assertTrue( match.matchSrcIPv4Net() );
+ }
+
+ @Test
+ public void testDstIPv4Net(){
+ assertEquals("ip2", ip2, match.dstIPv4Net() );
+ }
+
+ @Test
+ public void testDisableDstIPv4Net(){
+ match.disableDstIPv4Net();
+ assertEquals("dstIPv4Net", null, match.dstIPv4Net() );
+ assertFalse( match.matchDstIPv4Net() );
+ }
+
+ @Test
+ public void testMatchDstIPv4Net(){
+ assertTrue( match.matchDstIPv4Net() );
+ }
+
+ @Test
+ public void testIpProto(){
+ assertEquals("ip proto", ipproto, match.ipProto() );
+ }
+
+ @Test
+ public void testDisableIpProto(){
+ match.disableIpProto();
+ assertEquals("ipProto", null, match.ipProto() );
+ assertFalse( match.matchIpProto() );
+ }
+
+ @Test
+ public void testMatchIpProto(){
+ assertTrue( match.matchIpProto() );
+ }
+
+ @Test
+ public void testIpToS(){
+ assertEquals("tos", ipToS, match.ipToS() );
+ }
+
+ @Test
+ public void testDisableIpToS(){
+ match.disableIpToS();
+ assertEquals("ipToS", null, match.ipToS() );
+ assertFalse( match.matchIpToS() );
+ }
+
+ @Test
+ public void testMatchIpToS(){
+ assertTrue( match.matchIpToS() );
+ }
+
+ @Test
+ public void testSrcTcpUdpPort(){
+ assertEquals("src port", tport1, match.srcTcpUdpPort() );
+ }
+
+ @Test
+ public void testDisableSrcTcpUdpPort(){
+ match.disableSrcTcpUdpPort();
+ assertEquals("srcTcpUdpPort", null, match.srcTcpUdpPort() );
+ assertFalse( match.matchSrcTcpUdpPort() );
+ }
+
+ @Test
+ public void testMatchSrcTcpUdpPort(){
+ assertTrue( match.matchSrcTcpUdpPort() );
+ }
+
+ @Test
+ public void testDstTcpUdpPort(){
+ assertEquals("dst port", tport2, match.dstTcpUdpPort() );
+ }
+
+ @Test
+ public void testDisableDstTcpUdpPort(){
+ match.disableDstTcpUdpPort();
+ assertEquals("dstTcpUdpPort", null, match.dstTcpUdpPort() );
+ assertFalse( match.matchDstTcpUdpPort() );
+ }
+
+ @Test
+ public void testMatchDstTcpUdpPort(){
+ assertTrue( match.matchDstTcpUdpPort() );
+ }
+
+ @Test
+ public void testToString(){
+ FlowEntryMatch def = new FlowEntryMatch();
+ assertEquals("match default", def.toString(), "[]");
+
+ assertEquals("match set", match.toString(), "[inPort=1 srcMac=01:02:03:04:05:06 dstMac=06:05:04:03:02:01 ethernetFrameType=2 vlanId=3 vlanPriority=4 srcIPv4Net=127.0.0.1/32 dstIPv4Net=127.0.0.2/32 ipProto=5 ipToS=6 srcTcpUdpPort=7 dstTcpUdpPort=8]");
+ }
+
+}
diff --git a/src/test/java/net/onrc/onos/core/util/FlowEntryTest.java b/src/test/java/net/onrc/onos/core/util/FlowEntryTest.java
new file mode 100644
index 0000000..88a408a
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/util/FlowEntryTest.java
@@ -0,0 +1,279 @@
+package net.onrc.onos.core.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.FlowEntry;
+import net.onrc.onos.core.util.FlowEntryAction;
+import net.onrc.onos.core.util.FlowEntryActions;
+import net.onrc.onos.core.util.FlowEntryErrorState;
+import net.onrc.onos.core.util.FlowEntryId;
+import net.onrc.onos.core.util.FlowEntryMatch;
+import net.onrc.onos.core.util.FlowEntrySwitchState;
+import net.onrc.onos.core.util.FlowEntryUserState;
+import net.onrc.onos.core.util.FlowId;
+import net.onrc.onos.core.util.IPv4;
+import net.onrc.onos.core.util.IPv4Net;
+import net.onrc.onos.core.util.Port;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class FlowEntryTest {
+
+ FlowEntry entry;
+
+ FlowId flowId = new FlowId(0x1234);
+ FlowEntryId flowEntryId = new FlowEntryId(0x5678);
+ int idleTimeout = 5;
+ int hardTimeout = 10;
+ int priority = 15;
+ FlowEntryMatch match;
+ FlowEntryActions actions;
+
+ Dpid dpid = new Dpid(0xCAFE);
+
+ Port inport = new Port((short)1);
+ byte[] byte1 = { 1, 2, 3, 4, 5, 6 };
+ byte[] byte2 = { 6, 5, 4, 3, 2, 1 };
+ MACAddress mac1 = new MACAddress(byte1);
+ MACAddress mac2 = new MACAddress(byte2);
+ Short ether = Short.valueOf((short)2);
+ Short vlanid = Short.valueOf((short)3);
+ Byte vlanprio = Byte.valueOf((byte)4);
+ IPv4Net ip1 = new IPv4Net("127.0.0.1/32");
+ IPv4Net ip2 = new IPv4Net( new IPv4("127.0.0.2"), (short)32);
+ IPv4 ipaddr1 = new IPv4("127.0.0.3");
+ IPv4 ipaddr2 = new IPv4("127.0.0.4");
+ Byte ipproto = Byte.valueOf((byte)5);
+ Byte ipToS = Byte.valueOf((byte)6);
+ Short tport1 = Short.valueOf((short)7);
+ Short tport2 = Short.valueOf((short)8);
+ Port outport = new Port((short)9);
+ Port queueport = new Port((short)10);
+ int queueId = 11;
+
+ FlowEntryErrorState errorState = new FlowEntryErrorState( (short)12, (short)13);
+
+
+ @Before
+ public void setUp() throws Exception{
+ entry = new FlowEntry();
+
+ flowId = new FlowId("0x1234");
+ entry.setFlowId( flowId );
+
+ flowEntryId = new FlowEntryId("0x5678");
+ entry.setFlowEntryId(flowEntryId);
+
+ entry.setIdleTimeout(5);
+ entry.setHardTimeout(10);
+ entry.setPriority(15);
+
+ dpid = new Dpid("CA:FE");
+ entry.setDpid( dpid );
+
+ entry.setInPort( inport );
+ entry.setOutPort( outport );
+
+ match = new FlowEntryMatch();
+ match.enableInPort( inport);
+ match.enableSrcMac( mac1 );
+ match.enableDstMac( mac2 );
+ match.enableEthernetFrameType( ether );
+ match.enableVlanId( vlanid );
+ match.enableVlanPriority( vlanprio );
+ match.enableSrcIPv4Net( ip1 );
+ match.enableDstIPv4Net( ip2 );
+ match.enableIpProto( ipproto );
+ match.enableIpToS( ipToS );
+ match.enableSrcTcpUdpPort( tport1 );
+ match.enableDstTcpUdpPort( tport2 );
+
+ entry.setFlowEntryMatch( match );
+
+ FlowEntryAction action = null;
+ actions = entry.flowEntryActions();
+
+ action = new FlowEntryAction();
+ action.setActionOutput(outport);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionOutputToController((short)0);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetVlanId(vlanid);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetVlanPriority(vlanprio);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionStripVlan(true);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetEthernetSrcAddr(mac1);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetEthernetDstAddr(mac2);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetIPv4SrcAddr(ipaddr1);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetIPv4DstAddr(ipaddr2);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetIpToS(ipToS);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetTcpUdpSrcPort(tport1);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionSetTcpUdpDstPort(tport2);
+ actions.addAction(action);
+
+ action = new FlowEntryAction();
+ action.setActionEnqueue(queueport, queueId);
+ actions.addAction(action);
+
+ entry.setFlowEntryUserState( FlowEntryUserState.FE_USER_ADD );
+ entry.setFlowEntrySwitchState( FlowEntrySwitchState.FE_SWITCH_UPDATED );
+ entry.setFlowEntryErrorState( errorState );
+
+ }
+
+ @Test
+ public void testFlowEntry(){
+ FlowEntry e = new FlowEntry();
+
+ assertTrue( e.flowEntryActions().isEmpty() );
+ assertEquals("flowEntryUserState", FlowEntryUserState.FE_USER_UNKNOWN, e.flowEntryUserState() );
+ assertEquals("flowEntrySwitchState", FlowEntrySwitchState.FE_SWITCH_UNKNOWN, e.flowEntrySwitchState() );
+ }
+
+ @Test
+ public void testFlowId(){
+ assertEquals("flowId", flowId, entry.flowId() );
+ }
+
+ @Test
+ public void testIsValidFlowId(){
+ FlowEntry e = new FlowEntry();
+
+ // Test a Flow Entry with empty Flow ID
+ assertEquals("isValidFlowId", false, e.isValidFlowId() );
+
+ // Test a Flow Entry with invalid Flow ID
+ e.setFlowId(new FlowId());
+ assertEquals("isValidFlowId", false, e.isValidFlowId() );
+
+ // Test a Flow Entry with valid Flow ID
+ e.setFlowId(new FlowId(0x1));
+ assertEquals("isValidFlowId", true, e.isValidFlowId() );
+ assertEquals("isValidFlowId", true, entry.isValidFlowId() );
+ }
+
+ @Test
+ public void testFlowEntryId(){
+ assertEquals("flowEntryId", flowEntryId, entry.flowEntryId() );
+ }
+
+ @Test
+ public void testIsValidFlowEntryId(){
+ FlowEntry e = new FlowEntry();
+
+ // Test a Flow Entry with empty Flow Entry ID
+ assertEquals("isValidFlowEntryId", false, e.isValidFlowEntryId() );
+
+ // Test a Flow Entry with invalid Flow Entry ID
+ e.setFlowEntryId(new FlowEntryId());
+ assertEquals("isValidFlowEntryId", false, e.isValidFlowEntryId() );
+
+ // Test a Flow Entry with valid Flow Entry ID
+ e.setFlowEntryId(new FlowEntryId(0x1));
+ assertEquals("isValidFlowEntryId", true, e.isValidFlowEntryId() );
+ assertEquals("isValidFlowEntryId", true, entry.isValidFlowEntryId() );
+ }
+
+ @Test
+ public void testIdleTimeout(){
+ assertEquals("idleTimeout", idleTimeout, entry.idleTimeout() );
+ }
+
+ @Test
+ public void testHardTimeout(){
+ assertEquals("hardTimeout", hardTimeout, entry.hardTimeout() );
+ }
+
+ @Test
+ public void testPriority(){
+ assertEquals("priority", priority, entry.priority() );
+ }
+
+ @Test
+ public void testFlowEntryMatch(){
+ assertEquals("flowEntryMatch", match, entry.flowEntryMatch() );
+ }
+
+ @Test
+ public void testFlowEntryActions(){
+ assertEquals("flowEntryActions", actions, entry.flowEntryActions() );
+ }
+
+ @Test
+ public void testSetFlowEntryActions(){
+ FlowEntryActions actions = new FlowEntryActions();
+ entry.setFlowEntryActions( actions );
+ assertEquals("flowEntryActions", actions, entry.flowEntryActions() );
+ }
+
+ @Test
+ public void testDpid(){
+ assertEquals("dpid", dpid, entry.dpid() );
+ }
+
+ @Test
+ public void testInPort(){
+ assertEquals("inPort", inport, entry.inPort() );
+ }
+
+ @Test
+ public void testOutPort(){
+ assertEquals("outPort", outport, entry.outPort() );
+ }
+
+ @Test
+ public void testFlowEntryUserState(){
+ assertEquals("flowEntryUserState", FlowEntryUserState.FE_USER_ADD, entry.flowEntryUserState() );
+ }
+
+ @Test
+ public void testFlowEntrySwitchState(){
+ assertEquals("flowEntrySwitchState", FlowEntrySwitchState.FE_SWITCH_UPDATED, entry.flowEntrySwitchState() );
+ }
+
+ @Test
+ public void testFlowEntryErrorState(){
+ assertEquals("flowEntryErrorState", errorState, entry.flowEntryErrorState() );
+ }
+
+ @Test
+ public void testToString(){
+ FlowEntry def = new FlowEntry();
+ assertEquals("toString", def.toString(), "[ idleTimeout=0 hardTimeout=0 priority=32768 flowEntryActions=[] flowEntryUserState=FE_USER_UNKNOWN flowEntrySwitchState=FE_SWITCH_UNKNOWN]" );
+ assertEquals("toString", entry.toString(), "[flowEntryId=0x5678 flowId=0x1234 idleTimeout=5 hardTimeout=10 priority=15 flowEntryMatch=[inPort=1 srcMac=01:02:03:04:05:06 dstMac=06:05:04:03:02:01 ethernetFrameType=2 vlanId=3 vlanPriority=4 srcIPv4Net=127.0.0.1/32 dstIPv4Net=127.0.0.2/32 ipProto=5 ipToS=6 srcTcpUdpPort=7 dstTcpUdpPort=8] flowEntryActions=[[type=ACTION_OUTPUT action=[port=9 maxLen=0]];[type=ACTION_OUTPUT action=[port=-3 maxLen=0]];[type=ACTION_SET_VLAN_VID action=[vlanId=3]];[type=ACTION_SET_VLAN_PCP action=[vlanPriority=4]];[type=ACTION_STRIP_VLAN action=[stripVlan=true]];[type=ACTION_SET_DL_SRC action=[addr=01:02:03:04:05:06]];[type=ACTION_SET_DL_DST action=[addr=06:05:04:03:02:01]];[type=ACTION_SET_NW_SRC action=[addr=127.0.0.3]];[type=ACTION_SET_NW_DST action=[addr=127.0.0.4]];[type=ACTION_SET_NW_TOS action=[ipToS=6]];[type=ACTION_SET_TP_SRC action=[port=7]];[type=ACTION_SET_TP_DST action=[port=8]];[type=ACTION_ENQUEUE action=[port=10 queueId=11]];] dpid=00:00:00:00:00:00:ca:fe inPort=1 outPort=9 flowEntryUserState=FE_USER_ADD flowEntrySwitchState=FE_SWITCH_UPDATED flowEntryErrorState=[type=12 code=13]]" );
+ }
+
+}