Giant patch of changes to support OpenFlow 1.3
The following people have contributed to this patch:
- Ali Al-Shabibi <alshabibi.ali@gmail.com>
- Ayaka Koshibe <ayaka@onlab.us>
- Brian O'Connor <bocon@onlab.us>
- Jonathan Hart <jono@onlab.us>
- Matteo Gerola <mgerola@create-net.org>
- Michele Santuari <michele.santuari@create-net.org>
- Pavlin Radoslavov <pavlin@onlab.us>
- Saurav Das <sauravdas@alumni.stanford.edu>
- Toshio Koide <t-koide@onlab.us>
- Yuta HIGUCHI <y-higuchi@onlab.us>
The patch includes the following changes:
- New Floodlight I/O loop / state machine
- New switch/port handling
- New role management (incl. Role.EQUAL)
- Added Floodlight debug framework
- Updates to Controller.java
- Move to Loxigen's OpenflowJ library
- Added OF1.3 support
- Added support for different switches (via DriverManager)
- Updated ONOS modules to use new APIs
- Added and updated unit tests
Change-Id: Ic70a8d50f7136946193d2ba2e4dc0b4bfac5f599
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 89f188d..ae30949 100644
--- a/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java
+++ b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java
@@ -1,6 +1,6 @@
package net.onrc.onos.core.flowprogrammer;
-import static org.junit.Assert.assertEquals;
+
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -16,42 +16,41 @@
import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.internal.OFMessageFuture;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.util.OFMessageDamper;
-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.intent.FlowEntry;
+import net.onrc.onos.core.intent.IntentOperation.Operator;
import net.onrc.onos.core.util.IntegrationTest;
-import net.onrc.onos.core.util.PortNumber;
import org.easymock.EasyMock;
-import org.easymock.IAnswer;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-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;
+import org.projectfloodlight.openflow.protocol.OFBarrierReply;
+import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFFlowModify;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.match.Match;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.U64;
+
@Category(IntegrationTest.class)
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 OFFactory factory10 = OFFactories.getFactory(OFVersion.OF_10);
+
/**
* Test single OFMessage is correctly sent to single switch via MessageDamper.
*/
@@ -60,18 +59,20 @@
beginInitMock();
OFMessage msg = EasyMock.createMock(OFMessage.class);
- EasyMock.expect(msg.getXid()).andReturn(1).anyTimes();
- EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+ EasyMock.expect(msg.getXid()).andReturn((long) 1).anyTimes();
+ //EasyMock.expect(msg.()).andReturn((short) 100).anyTimes();
EasyMock.replay(msg);
IOFSwitch sw = createConnectedSwitchMock(1, false);
- EasyMock.replay(sw);
+
+
try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
- .andReturn(true).once();
+ sw.write(EasyMock.eq(msg), EasyMock.eq((FloodlightContext) null));
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(sw);
} catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
+ fail("Failed in IOFSwitch#write()");
}
endInitMock();
@@ -104,25 +105,24 @@
beginInitMock();
IOFSwitch sw = createConnectedSwitchMock(1, false);
- EasyMock.replay(sw);
+
List<OFMessage> messages = new ArrayList<OFMessage>();
for (int i = 0; i < numMsg; ++i) {
OFMessage msg = EasyMock.createMock(OFMessage.class);
- EasyMock.expect(msg.getXid()).andReturn(i).anyTimes();
- EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+ EasyMock.expect(msg.getXid()).andReturn((long) i).anyTimes();
EasyMock.replay(msg);
messages.add(msg);
try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
- .andReturn(true).once();
+ sw.write(EasyMock.eq(msg), EasyMock.eq((FloodlightContext) null));
+ EasyMock.expectLastCall().once();
} catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
+ fail("Failed in IOFSwitch#write()");
}
}
-
+ EasyMock.replay(sw);
endInitMock();
initPusher(1);
@@ -160,25 +160,24 @@
Map<IOFSwitch, List<OFMessage>> swMap = new HashMap<IOFSwitch, List<OFMessage>>();
for (int i = 0; i < numSwitch; ++i) {
IOFSwitch sw = createConnectedSwitchMock(i, false);
- EasyMock.replay(sw);
List<OFMessage> messages = new ArrayList<OFMessage>();
for (int j = 0; j < numMsg; ++j) {
OFMessage msg = EasyMock.createMock(OFMessage.class);
- EasyMock.expect(msg.getXid()).andReturn(j).anyTimes();
- EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+ EasyMock.expect(msg.getXid()).andReturn((long) j).anyTimes();
EasyMock.replay(msg);
messages.add(msg);
try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
- .andReturn(true).once();
+ sw.write(EasyMock.eq(msg), EasyMock.eq((FloodlightContext) null));
+ EasyMock.expectLastCall().once();
} catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
+ fail("Failed in IOFWrite#write()");
}
}
swMap.put(sw, messages);
+ EasyMock.replay(sw);
}
endInitMock();
@@ -223,30 +222,30 @@
Map<IOFSwitch, List<OFMessage>> swMap = new HashMap<IOFSwitch, List<OFMessage>>();
for (int i = 0; i < numThreads; ++i) {
IOFSwitch sw = createConnectedSwitchMock(i, false);
- EasyMock.replay(sw);
+ //EasyMock.replay(sw);
List<OFMessage> messages = new ArrayList<OFMessage>();
for (int j = 0; j < numMsg; ++j) {
OFMessage msg = EasyMock.createMock(OFMessage.class);
- EasyMock.expect(msg.getXid()).andReturn(j).anyTimes();
- EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+ EasyMock.expect(msg.getXid()).andReturn((long) j).anyTimes();
+
EasyMock.replay(msg);
messages.add(msg);
try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
- .andReturn(true).once();
+ sw.write(EasyMock.eq(msg), EasyMock.eq((FloodlightContext) null));
+ EasyMock.expectLastCall().once();
} catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
+ fail("Failed in IOFWrite#write()");
}
}
swMap.put(sw, messages);
+ EasyMock.replay(sw);
}
endInitMock();
initPusher(numThreads);
-
for (IOFSwitch sw : swMap.keySet()) {
for (OFMessage msg : swMap.get(sw)) {
boolean addResult = pusher.add(sw, msg);
@@ -292,42 +291,35 @@
beginInitMock();
IOFSwitch sw = createConnectedSwitchMock(1, true);
- EasyMock.replay(sw);
+ EasyMock.expect(sw.getOFVersion()).andReturn(OFVersion.OF_10).once();
+
List<OFMessage> messages = new ArrayList<OFMessage>();
for (int i = 0; i < numMsg; ++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.expect(msg.getXid()).andReturn((long) 1).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()");
+ sw.write(EasyMock.eq(msg), EasyMock.eq((FloodlightContext) null));
+ EasyMock.expectLastCall().once();
+ } catch (IOException e1) {
+ fail("Failed in IOFWrite#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();
+ sw.write(EasyMock.anyObject(OFBarrierRequest.class), EasyMock.eq((FloodlightContext) null));
+ EasyMock.expectLastCall().once();
+ barrierTime = System.currentTimeMillis();
} catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
+ fail("Failed in IOFWrite#write()");
}
+ EasyMock.replay(sw);
+
endInitMock();
initPusher(1);
@@ -370,19 +362,19 @@
beginInitMock();
IOFSwitch sw = createConnectedSwitchMock(1, true);
- EasyMock.replay(sw);
+ EasyMock.expect(sw.getOFVersion()).andReturn(OFVersion.OF_10).once();
try {
- EasyMock.expect(damper.write(EasyMock.eq(sw), (OFMessage) EasyMock.anyObject(), EasyMock.eq(context)))
- .andReturn(true).once();
+ sw.write((OFMessage) EasyMock.anyObject(), EasyMock.eq((FloodlightContext) null));
+ EasyMock.expectLastCall().once();
} catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
+ fail("Failed in IOFWrite#write()");
}
-
+ EasyMock.replay(sw);
endInitMock();
initPusher(1);
- OFBarrierReplyFuture future = pusher.barrierAsync(sw);
+ OFMessageFuture<OFBarrierReply> future = pusher.barrierAsync(sw);
assertNotNull(future);
@@ -397,7 +389,7 @@
pusher.stop();
}
- static final int XID_TO_VERIFY = 100;
+ static final long XID_TO_VERIFY = 100;
static final long DPID_TO_VERIFY = 10;
/**
@@ -407,7 +399,8 @@
@Test
public void testAddFlow() {
// instantiate required objects
- FlowEntry flowEntry1 = new FlowEntry();
+ FlowEntry flowEntry1 = new FlowEntry(DPID_TO_VERIFY, 1, 11, null, null, 0, 0, Operator.ADD);
+ /*
flowEntry1.setDpid(new Dpid(DPID_TO_VERIFY));
flowEntry1.setFlowId(new FlowId(1));
flowEntry1.setInPort(new PortNumber((short) 1));
@@ -417,46 +410,42 @@
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);
+ OFFlowModify fm = EasyMock.createMock(OFFlowModify.class);
- EasyMock.expect(factory.getMessage(EasyMock.eq(OFType.FLOW_MOD))).andReturn(msg);
+ OFFlowModify.Builder bld = EasyMock.createMock(OFFlowModify.Builder.class);
+
+ EasyMock.expect(bld.setIdleTimeout(EasyMock.anyInt())).andReturn(bld);
+ EasyMock.expect(bld.setHardTimeout(EasyMock.anyInt())).andReturn(bld);
+ EasyMock.expect(bld.setPriority(EasyMock.anyShort())).andReturn(bld);
+ EasyMock.expect(bld.setBufferId(OFBufferId.NO_BUFFER)).andReturn(bld);
+ EasyMock.expect(bld.setCookie(U64.of(EasyMock.anyLong()))).andReturn(bld);
+ EasyMock.expect(bld.setMatch(EasyMock.anyObject(Match.class))).andReturn(bld);
+ EasyMock.expect(bld.setActions((List<OFAction>) EasyMock.anyObject())).andReturn(bld);
+ EasyMock.expect(bld.setOutPort(OFPort.of(EasyMock.anyInt()))).andReturn(bld).atLeastOnce();
+ EasyMock.expect(bld.build()).andReturn(fm);
+
+ EasyMock.expect(fm.getXid()).andReturn(XID_TO_VERIFY).anyTimes();
+ EasyMock.expect(fm.getType()).andReturn(OFType.FLOW_MOD).anyTimes();
+
+
+
IOFSwitch sw = createConnectedSwitchMock(DPID_TO_VERIFY, false);
EasyMock.expect(sw.getStringId()).andReturn("1").anyTimes();
+ EasyMock.expect(sw.getOFVersion()).andReturn(OFVersion.OF_10).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();
+ sw.write(EasyMock.anyObject(OFMessage.class), EasyMock.eq((FloodlightContext) null));
+ EasyMock.expectLastCall().once();
} catch (IOException e1) {
- fail("Failed in OFMessageDamper#write()");
+ fail("Failed in IOFWrite#write()");
}
+ EasyMock.replay(bld, fm);
EasyMock.replay(sw);
endInitMock();
@@ -479,17 +468,20 @@
private void beginInitMock() {
context = EasyMock.createMock(FloodlightContext.class);
modContext = EasyMock.createMock(FloodlightModuleContext.class);
- factory = EasyMock.createMock(BasicFactory.class);
- damper = EasyMock.createMock(OFMessageDamper.class);
+ // AAS: I don't think we should mock factories... the rabbit whole is too deep.
+ //factory10 = EasyMock.createMock(OFFactories.getFactory(OFVersion.OF_10).getClass());
flProviderService = EasyMock.createMock(IFloodlightProviderService.class);
threadPoolService = EasyMock.createMock(IThreadPoolService.class);
+ EasyMock.expect(flProviderService.getOFMessageFactory_10()).andReturn(factory10).anyTimes();
+ EasyMock.expect(flProviderService.getOFMessageFactory_13()).andReturn(null).anyTimes();
EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IThreadPoolService.class)))
.andReturn(threadPoolService).once();
EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IFloodlightProviderService.class)))
.andReturn(flProviderService).once();
+ // AAS: FlowPusher doesn't call the following anymore.
flProviderService.addOFMessageListener(EasyMock.eq(OFType.BARRIER_REPLY),
- (FlowPusher) EasyMock.anyObject());
+ EasyMock.anyObject(FlowPusher.class));
EasyMock.expectLastCall().once();
ScheduledExecutorService executor = EasyMock.createMock(ScheduledExecutorService.class);
@@ -502,8 +494,7 @@
private void endInitMock() {
EasyMock.replay(threadPoolService);
EasyMock.replay(flProviderService);
- EasyMock.replay(damper);
- EasyMock.replay(factory);
+ //EasyMock.replay(factory10);
EasyMock.replay(modContext);
EasyMock.replay(context);
}
@@ -511,15 +502,14 @@
private void verifyAll() {
EasyMock.verify(threadPoolService);
EasyMock.verify(flProviderService);
- EasyMock.verify(damper);
- EasyMock.verify(factory);
+ //EasyMock.verify(factory10);
EasyMock.verify(modContext);
EasyMock.verify(context);
}
private void initPusher(int numThread) {
pusher = new FlowPusher(numThread);
- pusher.init(context, modContext, factory, damper);
+ pusher.init(modContext);
pusher.start();
}
@@ -528,7 +518,7 @@
EasyMock.expect(sw.isConnected()).andReturn(true).anyTimes();
EasyMock.expect(sw.getId()).andReturn(dpid).anyTimes();
sw.flush();
- EasyMock.expectLastCall().atLeastOnce();
+ EasyMock.expectLastCall().anyTimes();
if (useBarrier) {
prepareBarrier(sw);
}
@@ -537,14 +527,14 @@
}
private void prepareBarrier(IOFSwitch sw) {
+ OFBarrierRequest.Builder bld = EasyMock.createMock(factory10.buildBarrierRequest().getClass());
+ EasyMock.expect(bld.setXid(EasyMock.anyInt())).andReturn(bld);
+ EasyMock.expect(bld.getXid()).andReturn((long) 1).anyTimes();
+ EasyMock.expect(bld.getType()).andReturn(OFType.BARRIER_REQUEST).anyTimes();
+
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(bld.build()).andReturn(req).anyTimes();
+ EasyMock.replay(bld);
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 4be8f97..112620e 100644
--- a/src/test/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizerTest.java
+++ b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizerTest.java
@@ -6,6 +6,7 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -13,7 +14,7 @@
import net.floodlightcontroller.core.IOFSwitch;
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.intent.FlowEntry;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
@@ -22,15 +23,20 @@
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.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFFlowMod;
+import org.projectfloodlight.openflow.protocol.OFFlowModCommand;
+import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
+import org.projectfloodlight.openflow.protocol.OFFlowStatsReply;
+import org.projectfloodlight.openflow.protocol.OFFlowStatsRequest;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFStatsReply;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.types.U64;
// Test should be fixed to fit RAMCloud basis
@Ignore
@@ -42,8 +48,15 @@
private List<Long> idAdded;
private List<Long> idRemoved;
+ /*
+ * OF1.0 Factory for now. Change when we move to
+ * OF 1.3.
+ */
+ private static OFFactory factory10;
+
@Before
public void setUp() throws Exception {
+ factory10 = OFFactories.getFactory(OFVersion.OF_10);
idAdded = new ArrayList<Long>();
idRemoved = new ArrayList<Long>();
@@ -58,8 +71,8 @@
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());
+ if (fm.getCommand() == OFFlowModCommand.DELETE_STRICT) {
+ idRemoved.add(fm.getCookie().getValue());
}
}
return null;
@@ -71,7 +84,7 @@
@Override
public Object answer() throws Throwable {
FlowEntry flow = (FlowEntry) EasyMock.getCurrentArguments()[1];
- idAdded.add(flow.flowEntryId().value());
+ idAdded.add(flow.getFlowEntryId());
return null;
}
}).anyTimes();
@@ -206,13 +219,13 @@
IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
EasyMock.expect(sw.getId()).andReturn((long) 1).anyTimes();
- List<OFStatistics> stats = new ArrayList<OFStatistics>();
+ List<OFStatsReply> stats = new ArrayList<OFStatsReply>();
for (long cookie : cookieList) {
stats.add(createReply(cookie));
}
@SuppressWarnings("unchecked")
- Future<List<OFStatistics>> future = EasyMock.createMock(Future.class);
+ Future<List<OFStatsReply>> future = EasyMock.createMock(Future.class);
try {
EasyMock.expect(future.get()).andReturn(stats).once();
} catch (InterruptedException e1) {
@@ -223,7 +236,7 @@
EasyMock.replay(future);
try {
- EasyMock.expect(sw.getStatistics(EasyMock.anyObject(OFStatisticsRequest.class)))
+ EasyMock.expect(sw.getStatistics(EasyMock.anyObject(OFFlowStatsRequest.class)))
.andReturn(future).once();
} catch (IOException e) {
fail("Failed in IOFSwitch#getStatistics()");
@@ -239,13 +252,14 @@
* @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);
+ private OFFlowStatsReply createReply(long cookie) {
+ OFFlowStatsEntry entry = factory10.buildFlowStatsEntry()
+ .setCookie(U64.of(cookie))
+ .setPriority(1)
+ .setMatch(factory10.buildMatch().build())
+ .build();
+ OFFlowStatsReply stat = factory10.buildFlowStatsReply()
+ .setEntries(Collections.singletonList(entry)).build();
return stat;
}
diff --git a/src/test/java/net/onrc/onos/core/hostmanager/HostManagerTest.java b/src/test/java/net/onrc/onos/core/hostmanager/HostManagerTest.java
index 5f22091..7e552ed 100644
--- a/src/test/java/net/onrc/onos/core/hostmanager/HostManagerTest.java
+++ b/src/test/java/net/onrc/onos/core/hostmanager/HostManagerTest.java
@@ -39,8 +39,13 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFPacketIn;
+import org.projectfloodlight.openflow.protocol.OFPacketInReason;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.types.OFPort;
/**
* Unit tests for the Host Manager module (HostManger).
@@ -61,6 +66,7 @@
private IEventChannel<Long, Host> eventChannel;
private IFloodlightProviderService floodlightProvider;
private Date lastSeenTimestamp;
+ private OFFactory ofact;
@Override
@Before
@@ -102,6 +108,8 @@
modContext.addService(IFloodlightProviderService.class, floodlightProvider);
modContext.getServiceImpl(IFloodlightProviderService.class);
sw1Dpid = 1L;
+ ofact = OFFactories.getFactory(OFVersion.OF_10);
+
sw1 = createMockSwitch(sw1Dpid);
replay(sw1);
@@ -121,10 +129,8 @@
.setTtl((byte) 128)
.setSourceAddress("192.168.10.1")
.setDestinationAddress("192.168.255.255")
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[]{0x01}))));
+ .setPayload(getUDP(new Data(new byte[]{0x01}))));
+
/*
* Normal IPv4 packet
*/
@@ -137,10 +143,8 @@
.setTtl((byte) 128)
.setSourceAddress("192.168.1.1")
.setDestinationAddress("192.168.1.2")
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[]{0x01}))));
+ .setPayload(getUDP(new Data(new byte[]{0x01}))));
+
/*
* Same MAC header as pkt1,but not IP address set
*/
@@ -151,10 +155,8 @@
.setPayload(
new IPv4()
.setTtl((byte) 128)
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[]{0x01}))));
+ .setPayload(getUDP(new Data(new byte[]{0x01}))));
+
/*
* DHCP packet
*/
@@ -167,11 +169,7 @@
.setTtl((byte) 128)
.setSourceAddress("192.168.1.1")
.setDestinationAddress("192.168.1.2")
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setChecksum((short) 0)
- .setPayload(
+ .setPayload(getUDP(
new DHCP()
.setOpCode(DHCP.OPCODE_REPLY)
.setHardwareType(DHCP.HWTYPE_ETHERNET)
@@ -204,9 +202,8 @@
.setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
- this.pktIn = new OFPacketIn().setInPort((short) sw1DevPort);
-
- this.pktIn2 = new OFPacketIn().setInPort((short) sw1DevPort2);
+ this.pktIn = getPacketIn((short) sw1DevPort);
+ this.pktIn2 = getPacketIn((short) sw1DevPort2);
lastSeenTimestamp = new Date(1);
}
@@ -230,7 +227,8 @@
Ethernet eth = (Ethernet) pkt1;
Host srcHost = hostManager.getSourceHostFromPacket(eth, sw1Dpid, sw1DevPort);
- floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
+ floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN),
+ EasyMock.isA(HostManager.class));
srcHost.setLastSeenTimestamp(lastSeenTimestamp);
assertEquals(lastSeenTimestamp, srcHost.getLastSeenTimestamp());
}
@@ -278,7 +276,8 @@
hostManager.init(modContext);
hostManager.startUp(modContext);
- Command cmd = hostManager.processPacketIn(sw1, pktIn, (Ethernet) pkt1);
+ Command cmd = hostManager.processPacketIn(
+ sw1, pktIn, (Ethernet) pkt1, (short) sw1DevPort);
assertEquals(Command.CONTINUE, cmd);
EasyMock.verify(floodlightProvider);
@@ -297,7 +296,8 @@
hostManager.init(modContext);
hostManager.startUp(modContext);
- Command cmd = hostManager.processPacketIn(sw1, pktIn2, (Ethernet) pkt1);
+ Command cmd = hostManager.processPacketIn(
+ sw1, pktIn2, (Ethernet) pkt1, (short) sw1DevPort2);
assertEquals(Command.CONTINUE, cmd);
EasyMock.verify(floodlightProvider);
@@ -308,7 +308,8 @@
*/
@Test
public void testProcessPacketInStop() {
- Command cmd = hostManager.processPacketIn(sw1, pktIn, (Ethernet) pkt0);
+ Command cmd = hostManager.processPacketIn(
+ sw1, pktIn, (Ethernet) pkt0, (short) sw1DevPort);
assertEquals(Command.STOP, cmd);
}
@@ -322,7 +323,8 @@
Long longmac = eth.getSourceMAC().toLong();
Host srcHost = hostManager.getSourceHostFromPacket(eth, sw1Dpid, sw1DevPort);
- floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
+ floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN),
+ EasyMock.isA(HostManager.class));
EasyMock.expectLastCall();
floodlightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
EasyMock.expectLastCall();
@@ -344,7 +346,8 @@
Ethernet eth = (Ethernet) pkt1;
Host srcHost = hostManager.getSourceHostFromPacket(eth, sw1Dpid, sw1DevPort);
- floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
+ floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN),
+ EasyMock.isA(HostManager.class));
EasyMock.expectLastCall();
floodlightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
EasyMock.expectLastCall();
@@ -366,7 +369,8 @@
Ethernet eth = (Ethernet) pkt1;
MACAddress mac = eth.getSourceMAC();
- floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
+ floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN),
+ EasyMock.isA(HostManager.class));
EasyMock.expectLastCall();
floodlightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
EasyMock.expectLastCall();
@@ -378,4 +382,23 @@
EasyMock.verify(floodlightProvider);
}
+
+ /**
+ * Helper for building PacketIns. Defaults to a flowtable miss.
+ * @param inport the inport field value
+ * @return a PacketIn
+ */
+ private OFPacketIn getPacketIn(int inport) {
+ return ofact.buildPacketIn()
+ .setInPort(OFPort.of(inport))
+ .setReason(OFPacketInReason.NO_MATCH)
+ .build();
+ }
+
+ private UDP getUDP(IPacket payload) {
+ return (UDP) new UDP()
+ .setSourcePort((short) 5000)
+ .setDestinationPort((short) 5001)
+ .setPayload(payload);
+ }
}
diff --git a/src/test/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManagerTest.java b/src/test/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManagerTest.java
index 37adf6b..7f848a8 100644
--- a/src/test/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManagerTest.java
+++ b/src/test/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManagerTest.java
@@ -26,6 +26,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.IFloodlightProviderService;
@@ -42,15 +43,22 @@
import net.onrc.onos.core.registry.IControllerRegistryService;
import org.easymock.EasyMock;
+import org.easymock.IArgumentMatcher;
import org.junit.Before;
import org.junit.Test;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPortStatus;
-import org.openflow.protocol.OFPortStatus.OFPortReason;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFPacketIn;
+import org.projectfloodlight.openflow.protocol.OFPacketOut;
+import org.projectfloodlight.openflow.protocol.OFPortConfig;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortReason;
+import org.projectfloodlight.openflow.protocol.OFPortState;
+import org.projectfloodlight.openflow.protocol.OFPortStatus;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFPort;
// CHECKSTYLE IGNORE WriteTag FOR NEXT 2 LINES
/**
@@ -58,43 +66,109 @@
*/
public class LinkDiscoveryManagerTest extends FloodlightTestCase {
- private TestLinkDiscoveryManager ldm;
- protected static final Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
+ private LinkDiscoveryManager ldm;
- public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
- public boolean isSendLLDPsCalled = false;
- public boolean isClearLinksCalled = false;
+ private static final Set<OFPortState> EMPTY_PORT_STATE =
+ Collections.<OFPortState>emptySet();
- @Override
- protected void discoverOnAllPorts() {
- isSendLLDPsCalled = true;
- super.discoverOnAllPorts();
+ // Arbitrary MAC address that we can feed in to our mock objects. This
+ // value is never actually checked during the tests so it doesn't matter if
+ // all ports have the same MAC address.
+ private static final byte[] DEFAULT_MAC_ADDRESS =
+ new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
+
+ private OFFactory factory10 = OFFactories.getFactory(OFVersion.OF_10);
+
+ /**
+ * EasyMock matcher to verify the value of the output port of a packet out.
+ * This is used to verify that the packet out messages generated by
+ * LinkDiscoveryManager contain the correct output port.
+ *
+ */
+ private static final class PacketOutPortMatcher implements IArgumentMatcher {
+ private final int portNumber;
+
+ public PacketOutPortMatcher(int portNumber) {
+ this.portNumber = portNumber;
}
- public void reset() {
- isSendLLDPsCalled = false;
- isClearLinksCalled = false;
+ @Override
+ public void appendTo(StringBuffer strBuffer) {
+ strBuffer.append("PacketOutPortMatcher failed to verify output port");
+ }
+
+ @Override
+ public boolean matches(Object object) {
+ if (!(object instanceof OFPacketOut)) {
+ return false;
+ }
+
+ OFPacketOut po = (OFPacketOut) object;
+
+ if (po.getActions().size() != 1
+ || !(po.getActions().get(0) instanceof OFActionOutput)) {
+ return false;
+ }
+
+ OFActionOutput action = (OFActionOutput) po.getActions().get(0);
+
+ return action.getPort().getPortNumber() == portNumber;
}
}
- public LinkDiscoveryManager getTopology() {
+ /**
+ * Matcher method to match a given output port against a packet out message
+ * passed as an argument to a mock switch.
+ *
+ * @param outPort the output port to check in the packet out
+ * @return anything of type OFPacketOut
+ */
+ private static OFPacketOut matchOutPort(int outPort) {
+ EasyMock.reportMatcher(new PacketOutPortMatcher(outPort));
+ return null;
+ }
+
+ private LinkDiscoveryManager getLinkDiscoveryManager() {
return ldm;
}
- public IOFSwitch createMockSwitch(Long id) {
+ private IOFSwitch createMockSwitch(Long id) {
IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
expect(mockSwitch.getId()).andReturn(id).anyTimes();
expect(mockSwitch.portEnabled(EasyMock.anyShort())).andReturn(true).anyTimes();
return mockSwitch;
}
+ private OFPortDesc createMockPort(short portNumber) {
+ return createMockPortWithState(portNumber,
+ Collections.<OFPortState>emptySet());
+ }
+
+ private OFPortDesc createMockPortWithState(short portNumber,
+ Set<OFPortState> state) {
+ OFPort ofPort = EasyMock.createMock(OFPort.class);
+ expect(ofPort.getShortPortNumber()).andReturn(portNumber).anyTimes();
+
+ OFPortDesc ofPortDesc = EasyMock.createMock(OFPortDesc.class);
+ expect(ofPortDesc.getPortNo()).andReturn(ofPort).anyTimes();
+ expect(ofPortDesc.getHwAddr()).andReturn(
+ MacAddress.of(DEFAULT_MAC_ADDRESS)).anyTimes();
+ expect(ofPortDesc.getConfig()).
+ andReturn(Collections.<OFPortConfig>emptySet()).anyTimes();
+ expect(ofPortDesc.getState()).andReturn(state).anyTimes();
+
+ replay(ofPort);
+ replay(ofPortDesc);
+
+ return ofPortDesc;
+ }
+
@Override
@Before
public void setUp() throws Exception {
super.setUp();
FloodlightModuleContext cntx = new FloodlightModuleContext();
- ldm = new TestLinkDiscoveryManager();
- //ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
+ ldm = new LinkDiscoveryManager();
MockThreadPoolService tp = new MockThreadPoolService();
RestApiServer restApi = new RestApiServer();
IControllerRegistryService registry =
@@ -124,44 +198,46 @@
@Test
public void testAddOrUpdateLink() throws Exception {
- LinkDiscoveryManager topology = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Link lt = new Link(1L, 2, 2L, 1);
long firstSeenTime = System.currentTimeMillis();
LinkInfo info = new LinkInfo(firstSeenTime,
- System.currentTimeMillis(), 0, 0);
- topology.addOrUpdateLink(lt, info);
-
+ System.currentTimeMillis(), EMPTY_PORT_STATE,
+ EMPTY_PORT_STATE);
+ linkDiscovery.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));
+ assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+ assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
+ assertNotNull(linkDiscovery.portLinks.get(srcNpt));
+ assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
+ assertNotNull(linkDiscovery.portLinks.get(dstNpt));
+ assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
+ assertTrue(linkDiscovery.links.containsKey(lt));
- LinkInfo infoToVerify = topology.links.get(lt);
+ LinkInfo infoToVerify = linkDiscovery.links.get(lt);
assertEquals(firstSeenTime, infoToVerify.getFirstSeenTime());
- assertEquals(0, infoToVerify.getSrcPortState());
- assertEquals(0, infoToVerify.getDstPortState());
+ assertEquals(EMPTY_PORT_STATE, infoToVerify.getSrcPortState());
+ assertEquals(EMPTY_PORT_STATE, infoToVerify.getDstPortState());
// Arbitrary new port states to verify that the port state is updated
- final int newSrcPortState = 1;
- final int newDstPortState = 2;
+ final Set<OFPortState> newSrcPortState =
+ Collections.singleton(OFPortState.STP_BLOCK);
+ final Set<OFPortState> newDstPortState =
+ Collections.singleton(OFPortState.LINK_DOWN);
// Update the last received probe timestamp and the port states
LinkInfo infoWithStateChange = new LinkInfo(System.currentTimeMillis(),
System.currentTimeMillis(), newSrcPortState, newDstPortState);
- topology.addOrUpdateLink(lt, infoWithStateChange);
+ linkDiscovery.addOrUpdateLink(lt, infoWithStateChange);
- assertNotNull(topology.links.get(lt));
- infoToVerify = topology.links.get(lt);
+ assertNotNull(linkDiscovery.links.get(lt));
+ infoToVerify = linkDiscovery.links.get(lt);
// First seen time should be the original time, not the second update time
assertEquals(firstSeenTime, infoToVerify.getFirstSeenTime());
// Both port states should have been updated
@@ -171,114 +247,114 @@
@Test
public void testDeleteLink() throws Exception {
- LinkDiscoveryManager topology = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Link lt = new Link(1L, 2, 2L, 1);
LinkInfo info = new LinkInfo(System.currentTimeMillis(),
- System.currentTimeMillis(), 0, 0);
- topology.addOrUpdateLink(lt, info);
- topology.deleteLinks(Collections.singletonList(lt));
+ System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+ linkDiscovery.addOrUpdateLink(lt, info);
+ linkDiscovery.deleteLinks(Collections.singletonList(lt));
// 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());
+ assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+ assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
+ assertNull(linkDiscovery.portLinks.get(lt.getSrc()));
+ assertNull(linkDiscovery.portLinks.get(lt.getDst()));
+ assertTrue(linkDiscovery.links.isEmpty());
}
@Test
public void testAddOrUpdateLinkToSelf() throws Exception {
- LinkDiscoveryManager topology = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
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(), 0, 0);
- topology.addOrUpdateLink(lt, info);
+ System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+ linkDiscovery.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));
+ assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+ assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
+ assertNotNull(linkDiscovery.portLinks.get(srcNpt));
+ assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
+ assertNotNull(linkDiscovery.portLinks.get(dstNpt));
+ assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
+ assertTrue(linkDiscovery.links.containsKey(lt));
}
@Test
public void testDeleteLinkToSelf() throws Exception {
- LinkDiscoveryManager topology = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
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(), 0, 0);
- topology.addOrUpdateLink(lt, info);
- topology.deleteLinks(Collections.singletonList(lt));
+ System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+ linkDiscovery.addOrUpdateLink(lt, info);
+ linkDiscovery.deleteLinks(Collections.singletonList(lt));
// 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());
+ assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+ assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
+ assertNull(linkDiscovery.portLinks.get(srcNpt));
+ assertNull(linkDiscovery.portLinks.get(dstNpt));
+ assertTrue(linkDiscovery.links.isEmpty());
}
@Test
public void testRemovedSwitch() {
- LinkDiscoveryManager topology = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
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(), 0, 0);
- topology.addOrUpdateLink(lt, info);
+ System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+ linkDiscovery.addOrUpdateLink(lt, info);
IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
// Mock up our expected behavior
- topology.removedSwitch(sw1);
+ linkDiscovery.switchDisconnected(sw1.getId());
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());
+ assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+ assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
+ assertNull(linkDiscovery.portLinks.get(srcNpt));
+ assertNull(linkDiscovery.portLinks.get(dstNpt));
+ assertTrue(linkDiscovery.links.isEmpty());
}
@Test
public void testRemovedSwitchSelf() {
- LinkDiscoveryManager topology = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
IOFSwitch sw1 = createMockSwitch(1L);
replay(sw1);
Link lt = new Link(1L, 2, 1L, 3);
LinkInfo info = new LinkInfo(System.currentTimeMillis(),
- System.currentTimeMillis(), 0, 0);
- topology.addOrUpdateLink(lt, info);
+ System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+ linkDiscovery.addOrUpdateLink(lt, info);
// Mock up our expected behavior
- topology.removedSwitch(sw1);
+ linkDiscovery.switchDisconnected(sw1.getId());
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());
+ assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+ assertNull(linkDiscovery.portLinks.get(lt.getSrc()));
+ assertNull(linkDiscovery.portLinks.get(lt.getDst()));
+ assertTrue(linkDiscovery.links.isEmpty());
}
@Test
public void testAddUpdateLinks() throws Exception {
- LinkDiscoveryManager topology = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Link lt = new Link(1L, 1, 2L, 1);
NodePortTuple srcNpt = new NodePortTuple(1L, 1);
@@ -286,31 +362,34 @@
LinkInfo info;
+ // Setting the last LLDP reception time to be 40 seconds old, so we
+ // can use this to test that an old link times out correctly
info = new LinkInfo(System.currentTimeMillis() - 40000,
- System.currentTimeMillis() - 40000, 0, 0);
- topology.addOrUpdateLink(lt, info);
+ System.currentTimeMillis() - 40000,
+ EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+ linkDiscovery.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));
+ assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+ assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
+ assertNotNull(linkDiscovery.portLinks.get(srcNpt));
+ assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
+ assertNotNull(linkDiscovery.portLinks.get(dstNpt));
+ assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
+ assertTrue(linkDiscovery.links.containsKey(lt));
- topology.timeOutLinks();
+ linkDiscovery.timeOutLinks();
- // Add a link info based on info that would 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.
+ // Setting the last LLDP reception time to be 40 seconds old, so we
+ // can use this to test that an old link times out correctly
info = new LinkInfo(System.currentTimeMillis() - 40000,
- System.currentTimeMillis() - 40000, 0, 0);
- topology.addOrUpdateLink(lt, info);
+ System.currentTimeMillis() - 40000,
+ EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+ linkDiscovery.addOrUpdateLink(lt, info);
// Expect to timeout the unicast Valid Time, so the link should disappear
- topology.timeOutLinks();
- assertTrue(topology.links.get(lt) == null);
+ linkDiscovery.timeOutLinks();
+ assertTrue(linkDiscovery.links.get(lt) == null);
}
/**
@@ -322,58 +401,49 @@
*/
@Test
public void testSendDiscoveryMessage() throws IOException {
- byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
-
- LinkDiscoveryManager topology = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
// Mock up our expected behavior
IOFSwitch swTest = createMockSwitch(3L);
getMockFloodlightProvider().getSwitches().put(3L, swTest);
short portNum = 1;
- OFPhysicalPort ofpPort = new OFPhysicalPort();
- ofpPort.setPortNumber(portNum);
- ofpPort.setHardwareAddress(macAddress);
- /* sendDiscoverMessage() should perform the following actions on
- * IOFSwitch object
- * - getPort() with argument as "1"
- * - write() with OFPacketOut
- * - flush()
- */
- expect(swTest.getPort(portNum)).andReturn(ofpPort).atLeastOnce();
- swTest.write(EasyMock.anyObject(OFMessage.class), EasyMock.anyObject(FloodlightContext.class));
+ OFPortDesc ofPortDesc = createMockPort(portNum);
+
+ expect(swTest.getPort(portNum)).andReturn(ofPortDesc).atLeastOnce();
+ swTest.write(matchOutPort(portNum),
+ EasyMock.anyObject(FloodlightContext.class));
EasyMock.expectLastCall().times(1);
swTest.flush();
EasyMock.expectLastCall().once();
replay(swTest);
- topology.sendDiscoveryMessage(3L, portNum, false);
+ linkDiscovery.sendDiscoveryMessage(3L, portNum, false);
verify(swTest);
}
@Test
public void testHandlePortStatusForNewPort() throws IOException {
- byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
-
- LinkDiscoveryManager linkDiscovery = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
long dpid = 3L;
IOFSwitch sw = createMockSwitch(dpid);
getMockFloodlightProvider().getSwitches().put(dpid, sw);
short portNum = 1;
- OFPhysicalPort ofpPort = new OFPhysicalPort();
- ofpPort.setPortNumber(portNum);
- ofpPort.setHardwareAddress(macAddress);
- OFPortStatus portStatus = new OFPortStatus();
- portStatus.setDesc(ofpPort);
- portStatus.setReason((byte) OFPortReason.OFPPR_ADD.ordinal());
+ OFPortDesc ofPortDesc = createMockPort(portNum);
- expect(sw.getPort(portNum)).andReturn(ofpPort).anyTimes();
- sw.write(EasyMock.anyObject(OFMessage.class),
+ OFPortStatus portStatus = factory10.buildPortStatus()
+ .setDesc(ofPortDesc)
+ .setReason(OFPortReason.ADD)
+ .build();
+
+ expect(sw.getPort(portNum)).andReturn(ofPortDesc).once();
+
+ sw.write(matchOutPort(portNum),
EasyMock.anyObject(FloodlightContext.class));
sw.flush();
@@ -386,47 +456,41 @@
@Test
public void testHandlePortStatusForExistingPort() {
- byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
-
- LinkDiscoveryManager linkDiscovery = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
// Add a link that we can update later during the test
Link lt = new Link(1L, 1, 2L, 1);
LinkInfo info = new LinkInfo(System.currentTimeMillis(),
- System.currentTimeMillis(), 0, 0);
+ System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
linkDiscovery.addOrUpdateLink(lt, info);
short portNum = 1;
- // src port
- int srcPortState = 2;
- OFPhysicalPort srcPort = new OFPhysicalPort();
- srcPort.setPortNumber(portNum);
- srcPort.setHardwareAddress(macAddress);
- srcPort.setState(srcPortState);
- // dst port
- int dstPortState = 4;
- OFPhysicalPort dstPort = new OFPhysicalPort();
- dstPort.setPortNumber(portNum);
- dstPort.setHardwareAddress(macAddress);
- dstPort.setState(dstPortState);
+ // Arbitrary states to test state changes
+ Set<OFPortState> srcPortState =
+ Collections.singleton(OFPortState.STP_FORWARD);
+ Set<OFPortState> dstPortState =
+ Collections.singleton(OFPortState.STP_LISTEN);
- OFPortStatus srcPortStatus = new OFPortStatus();
- srcPortStatus.setDesc(srcPort);
- srcPortStatus.setReason((byte) OFPortReason.OFPPR_MODIFY.ordinal());
+ OFPortDesc srcPortDesc = createMockPortWithState(portNum, srcPortState);
+ OFPortDesc dstPortDesc = createMockPortWithState(portNum, dstPortState);
- OFPortStatus dstPortStatus = new OFPortStatus();
- dstPortStatus.setDesc(dstPort);
- dstPortStatus.setReason((byte) OFPortReason.OFPPR_MODIFY.ordinal());
+ OFPortStatus srcPortStatus = factory10.buildPortStatus()
+ .setDesc(srcPortDesc)
+ .setReason(OFPortReason.MODIFY)
+ .build();
+
+ OFPortStatus dstPortStatus = factory10.buildPortStatus()
+ .setDesc(dstPortDesc)
+ .setReason(OFPortReason.MODIFY)
+ .build();
linkDiscovery.handlePortStatus(
getMockFloodlightProvider().getSwitches().get(1L), srcPortStatus);
-
LinkInfo newInfo = linkDiscovery.links.get(lt);
assertEquals(srcPortState, newInfo.getSrcPortState());
- assertEquals(0, newInfo.getDstPortState());
-
+ assertEquals(EMPTY_PORT_STATE, newInfo.getDstPortState());
linkDiscovery.handlePortStatus(
getMockFloodlightProvider().getSwitches().get(2L), dstPortStatus);
@@ -438,26 +502,21 @@
@Test
public void testHandlePortStatusForDeletePort() {
- byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
-
- LinkDiscoveryManager linkDiscovery = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
// Add a link that we can delete later during the test
Link lt = new Link(1L, 1, 2L, 2);
LinkInfo info = new LinkInfo(System.currentTimeMillis(),
- System.currentTimeMillis(), 0, 0);
+ System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
linkDiscovery.addOrUpdateLink(lt, info);
short portNum = 1;
- int srcPortState = 1;
- OFPhysicalPort srcPort = new OFPhysicalPort();
- srcPort.setPortNumber(portNum);
- srcPort.setHardwareAddress(macAddress);
- srcPort.setState(srcPortState);
- OFPortStatus srcPortStatus = new OFPortStatus();
- srcPortStatus.setDesc(srcPort);
- srcPortStatus.setReason((byte) OFPortReason.OFPPR_DELETE.ordinal());
+ OFPortDesc srcPortDesc = createMockPort(portNum);
+ OFPortStatus srcPortStatus = factory10.buildPortStatus()
+ .setDesc(srcPortDesc)
+ .setReason(OFPortReason.DELETE)
+ .build();
assertNotNull(linkDiscovery.getLinks().get(lt));
@@ -471,8 +530,6 @@
@Test
public void testReceive() {
- byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
-
OnosLldp lldpPacket = new OnosLldp();
lldpPacket.setPort((short) 1);
lldpPacket.setSwitch(1L);
@@ -480,24 +537,24 @@
Ethernet ethPacket = new Ethernet();
ethPacket.setEtherType(Ethernet.TYPE_LLDP);
- ethPacket.setSourceMACAddress(macAddress);
+ ethPacket.setSourceMACAddress(DEFAULT_MAC_ADDRESS);
ethPacket.setDestinationMACAddress(
LinkDiscoveryManager.LLDP_STANDARD_DST_MAC_STRING);
ethPacket.setPayload(lldpPacket);
ethPacket.setPad(true);
- OFPacketIn pi = new OFPacketIn();
- pi.setInPort((short) 2);
- pi.setPacketData(ethPacket.serialize());
+ OFPacketIn pi = EasyMock.createMock(OFPacketIn.class);
+ expect(pi.getData()).andReturn(ethPacket.serialize()).anyTimes();
+ replay(pi);
- LinkDiscoveryManager linkDiscovery = getTopology();
+ LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Link expectedLink = new Link(1L, 1, 2L, 2);
assertNull(linkDiscovery.links.get(expectedLink));
// Sending in the LLDP packet should cause the link to be created
- Command command = linkDiscovery.handleLldp(lldpPacket, 2L, pi);
+ Command command = linkDiscovery.handleLldp(lldpPacket, 2L, pi, (short) 2);
assertEquals(Command.STOP, command);
assertNotNull(linkDiscovery.links.get(expectedLink));