diff --git a/src/main/java/net/floodlightcontroller/core/IOFMessageWriter.java b/src/main/java/net/floodlightcontroller/core/IOFMessageWriter.java index bd27181f19e9170fac71db1557942dcc8cef0510..a8a7e3191dda047e57a143f959be27cb5ba5dbae 100644 --- a/src/main/java/net/floodlightcontroller/core/IOFMessageWriter.java +++ b/src/main/java/net/floodlightcontroller/core/IOFMessageWriter.java @@ -17,6 +17,7 @@ package net.floodlightcontroller.core; +import java.util.Collection; import java.util.List; import org.projectfloodlight.openflow.protocol.OFMessage; @@ -33,25 +34,24 @@ import com.google.common.util.concurrent.ListenableFuture; public interface IOFMessageWriter{ - /** - * Writes to the OFMessage to the output stream. - * - * <p><b>Note:</b> this method has fire-and-forget semantics. When the connection is - * not currently connected, it will silently discard the messages. + /** + * Writes the OFMessage to the output stream. * * @param m + * @return true upon success; false if message could not be written */ - void write(OFMessage m); + boolean write(OFMessage m); /** * Writes the list of messages to the output stream. * - * <p><b>Note:</b> this method has fire-and-forget semantics. When the connection is - * not currently connected, it will silently discard the messages. + * Any messages that could not be written due to channel disconnect + * will be returned. * * @param msglist + * @return list of messages that could not be written */ - void write(Iterable<OFMessage> msglist); + Collection<OFMessage> write(Iterable<OFMessage> msgList); /** write an OpenFlow Request message, register for a single corresponding reply message * or error message. diff --git a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java index cc138ecc6207be57b387c89c630faeb92b224aad..b6a96f31ffc161d5443ee066acaefd9ffc136bdb 100644 --- a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java +++ b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java @@ -300,15 +300,17 @@ public interface IOFSwitch extends IOFMessageWriter { * Writes a message to the connection specified by the logical OFMessage category * @param m an OF Message * @param category the category of the OF Message to be sent + * @return true upon success; false upon failure */ - void write(OFMessage m, LogicalOFMessageCategory category); + boolean write(OFMessage m, LogicalOFMessageCategory category); /** * Writes a message list to the connection specified by the logical OFMessage category * @param msglist an OF Message list * @param category the category of the OF Message list to be sent + * @return list of failed messages, if any; success denoted by empty list */ - void write(Iterable<OFMessage> msglist, LogicalOFMessageCategory category); + Iterable<OFMessage> write(Iterable<OFMessage> msglist, LogicalOFMessageCategory category); /** * Get a connection specified by the logical OFMessage category diff --git a/src/main/java/net/floodlightcontroller/core/internal/NullConnection.java b/src/main/java/net/floodlightcontroller/core/internal/NullConnection.java index 75ce28049cc4b086d5bf1c5ac3a6d3872b48d0c9..4854a1341a868771d42914197944a0465288430a 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/NullConnection.java +++ b/src/main/java/net/floodlightcontroller/core/internal/NullConnection.java @@ -1,12 +1,14 @@ package net.floodlightcontroller.core.internal; import java.net.SocketAddress; +import java.util.Collection; import java.util.List; import java.util.Date; import net.floodlightcontroller.core.IOFConnectionBackend; import net.floodlightcontroller.core.IOFMessageWriter; import net.floodlightcontroller.core.SwitchDisconnectedException; +import net.floodlightcontroller.util.IterableUtils; import org.projectfloodlight.openflow.protocol.OFFactories; import org.projectfloodlight.openflow.protocol.OFFactory; @@ -42,13 +44,15 @@ public class NullConnection implements IOFConnectionBackend, IOFMessageWriter { } @Override - public void write(OFMessage m) { + public boolean write(OFMessage m) { warn(); + return false; } @Override - public void write(Iterable<OFMessage> msglist) { + public Collection<OFMessage> write(Iterable<OFMessage> msgList) { warn(); + return IterableUtils.toCollection(msgList); } @Override diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFConnection.java b/src/main/java/net/floodlightcontroller/core/internal/OFConnection.java index 1039a0e933926577efeb5b26f229c66431146cf4..0bf1afadc329daeed35cb92494fdc63f4b9edb56 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/OFConnection.java +++ b/src/main/java/net/floodlightcontroller/core/internal/OFConnection.java @@ -19,6 +19,7 @@ package net.floodlightcontroller.core.internal; import java.net.SocketAddress; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -42,6 +43,7 @@ import net.floodlightcontroller.core.IOFConnection; import net.floodlightcontroller.core.IOFConnectionBackend; import net.floodlightcontroller.core.SwitchDisconnectedException; import net.floodlightcontroller.debugcounter.IDebugCounterService; +import net.floodlightcontroller.util.IterableUtils; import org.projectfloodlight.openflow.protocol.OFErrorMsg; import org.projectfloodlight.openflow.protocol.OFFactory; @@ -148,27 +150,39 @@ public class OFConnection implements IOFConnection, IOFConnectionBackend{ /** * All write methods chain into this write() to use WriteMessageTask. + * + * Write the list of messages to the switch + * + * @param msgList list of messages to write + * @return list of failed messages; can only fail if channel disconnected */ @Override - public void write(final Iterable<OFMessage> msgList) { + public Collection<OFMessage> write(final Iterable<OFMessage> msgList) { if (!isConnected()) { if (logger.isDebugEnabled()) logger.debug(this.toString() + " : not connected - dropping {} element msglist {} ", Iterables.size(msgList), String.valueOf(msgList).substring(0, 80)); - return; + return IterableUtils.toCollection(msgList); } - for (OFMessage m : msgList) { - if (logger.isTraceEnabled()) + for (OFMessage m : msgList) { + if (logger.isTraceEnabled()) { logger.trace("{}: send {}", this, m); - counters.updateWriteStats(m); + counters.updateWriteStats(m); + } } this.channel.eventLoop().execute(new WriteMessageTask(msgList)); + return Collections.emptyList(); } + /** + * Write the single message to the channel + * @param m + * @return true upon success; false upon failure; can only fail if channel disconnected + */ @Override - public void write(OFMessage m) { - this.write(Collections.singletonList(m)); + public boolean write(OFMessage m) { + return this.write(Collections.singletonList(m)).isEmpty(); } @Override diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitch.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitch.java index d9f6ea24bce4032c41f4624eaf81adc841ed50e6..afb7eed40e0c816729a8524d3a9002daad689ec7 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitch.java +++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitch.java @@ -27,6 +27,8 @@ import java.util.Comparator; import java.util.Date; import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -71,6 +73,7 @@ import org.projectfloodlight.openflow.protocol.OFStatsReply; import org.projectfloodlight.openflow.protocol.OFStatsRequest; import org.projectfloodlight.openflow.protocol.OFTableFeatures; import org.projectfloodlight.openflow.protocol.OFTableFeaturesStatsReply; +import org.projectfloodlight.openflow.protocol.OFType; import org.projectfloodlight.openflow.protocol.OFVersion; import org.projectfloodlight.openflow.types.DatapathId; import org.projectfloodlight.openflow.types.OFAuxId; @@ -78,6 +81,7 @@ import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.TableId; import org.projectfloodlight.openflow.types.U64; +import net.floodlightcontroller.util.IterableUtils; import net.floodlightcontroller.util.LinkedHashSetWrapper; import net.floodlightcontroller.util.OrderedCollection; @@ -677,6 +681,66 @@ public class OFSwitch implements IOFSwitchBackend { } } + protected static class SwitchRoleMessageValidator { + private static final Map<OFVersion, Set<OFType>> validSlaveMsgsByOFVersion; + static { + Map<OFVersion, Set<OFType>> m = new HashMap<OFVersion, Set<OFType>>(); + Set<OFType> s = new HashSet<OFType>(); + s.add(OFType.ROLE_REQUEST); + s.add(OFType.SET_ASYNC); + s.add(OFType.SET_CONFIG); + s.add(OFType.GET_ASYNC_REQUEST); + s.add(OFType.ECHO_REQUEST); + s.add(OFType.GET_CONFIG_REQUEST); + s.add(OFType.STATS_REQUEST); + s.add(OFType.FEATURES_REQUEST); + m.put(OFVersion.OF_10, Collections.unmodifiableSet(s)); + s = new HashSet<OFType>(); + m.put(OFVersion.OF_11, Collections.unmodifiableSet(s)); + s = new HashSet<OFType>(); + m.put(OFVersion.OF_12, Collections.unmodifiableSet(s)); + s = new HashSet<OFType>(); + m.put(OFVersion.OF_13, Collections.unmodifiableSet(s)); + s = new HashSet<OFType>(); + m.put(OFVersion.OF_14, Collections.unmodifiableSet(s)); + + validSlaveMsgsByOFVersion = Collections.unmodifiableMap(m); + } + + /** + * Sorts any invalid messages by moving them from the msgList. The net result + * is a new list returned containing the invalid messages and a pruned msgList + * containing only those messages that are valid for the given role of the controller + * and OpenFlow version of the switch. + * + * @param msgList the list of messages to sort + * @param valid the list of valid messages (caller must allocate) + * @param swVersion the OFVersion of the switch + * @param isSlave true if controller is slave; false otherwise + * @return list of messages that are not valid, removed from input parameter msgList + */ + protected static Collection<OFMessage> pruneInvalidMessages(Iterable<OFMessage> msgList, Collection<OFMessage> valid, OFVersion swVersion, boolean isActive) { + if (isActive) { /* master or equal/other support all */ + valid.addAll(IterableUtils.toCollection(msgList)); + return Collections.emptyList(); + } else { /* slave */ + Set<OFType> validSlaveMsgs = validSlaveMsgsByOFVersion.get(swVersion); + List<OFMessage> invalid = new ArrayList<OFMessage>(); + Iterator<OFMessage> itr = msgList.iterator(); + while (itr.hasNext()) { + OFMessage m = itr.next(); + if (!validSlaveMsgs.contains(m.getType())) { + invalid.add(m); + } else { + valid.add(m); + } + } + + return invalid; + } + } + } + @Override public boolean attributeEquals(String name, Object other) { Object attr = this.attributes.get(name); @@ -735,14 +799,14 @@ public class OFSwitch implements IOFSwitchBackend { */ public IOFConnection getConnection(OFAuxId auxId) { IOFConnection connection = this.connections.get(auxId); - if(connection == null){ + if (connection == null) { throw new IllegalArgumentException("OF Connection for " + this + " with " + auxId + " does not exist."); } return connection; } public IOFConnection getConnection(LogicalOFMessageCategory category) { - if(switchManager.isCategoryRegistered(category)){ + if (switchManager.isCategoryRegistered(category)) { return getConnection(category.getAuxId()); } else{ @@ -750,37 +814,72 @@ public class OFSwitch implements IOFSwitchBackend { } } + /** + * Write a single message to the switch + * + * @param m the message to write + * @return true upon success; false upon failure; + * failure can occur either from sending a message not supported in the current role, or + * from the channel being disconnected + */ @Override - public void write(OFMessage m) { - this.write(Collections.singletonList(m)); + public boolean write(OFMessage m) { + return this.write(Collections.singletonList(m)).isEmpty(); } - + + + /** + * Write a list of messages to the switch + * + * @param msglist list of messages to write + * @return list of failed messages; messages can fail if sending the messages is not supported + * in the current role, or from the channel becoming disconnected + */ @Override - public void write(Iterable<OFMessage> msglist) { - if (isActive()) { - connections.get(OFAuxId.MAIN).write(msglist); - for (OFMessage m : msglist) { - switchManager.handleOutgoingMessage(this, m); - } - } else { - log.warn("Attempted to write to switch {} that is SLAVE.", this.getId().toString()); - } + public Collection<OFMessage> write(Iterable<OFMessage> msglist) { + return this.write(msglist, LogicalOFMessageCategory.MAIN); } - + @Override - public void write(OFMessage m, LogicalOFMessageCategory category) { - this.write(Collections.singletonList(m), category); + public boolean write(OFMessage m, LogicalOFMessageCategory category) { + return this.write(Collections.singletonList(m), category).isEmpty(); } @Override - public void write(Iterable<OFMessage> msglist, LogicalOFMessageCategory category) { - if (isActive()) { - this.getConnection(category).write(msglist); - for (OFMessage m : msglist) { - switchManager.handleOutgoingMessage(this, m); + public Collection<OFMessage> write(Iterable<OFMessage> msgList, LogicalOFMessageCategory category) { + IOFConnection conn = this.getConnection(category); /* do first to check for supported category */ + Collection<OFMessage> validMsgs = new ArrayList<OFMessage>(); + Collection<OFMessage> invalidMsgs = SwitchRoleMessageValidator.pruneInvalidMessages( + msgList, validMsgs, this.getOFFactory().getVersion(), this.isActive()); + if (log.isDebugEnabled()) { + log.debug("MESSAGES: {}, VALID: {}, INVALID: {}", new Object[] { msgList, validMsgs, invalidMsgs}); + } + /* Try to write all valid messages */ + Collection<OFMessage> unsent = conn.write(validMsgs); + for (OFMessage m : validMsgs) { + if (!unsent.contains(m)) { + switchManager.handleOutgoingMessage(this, m); } + } + + /* Collect invalid and unsent messages */ + Collection<OFMessage> ret = null; + if (!unsent.isEmpty()) { + log.warn("Could not send messages {} due to channel disconnection on switch {}", unsent, this.getId()); + ret = IterableUtils.toCollection(unsent); + } + if (!invalidMsgs.isEmpty()) { + log.warn("Could not send messages {} while in SLAVE role on switch {}", invalidMsgs, this.getId()); + if (ret == null) { + ret = IterableUtils.toCollection(invalidMsgs); + } else { + ret.addAll(IterableUtils.toCollection(invalidMsgs)); + } + } + if (ret == null) { + return Collections.emptyList(); } else { - log.warn("Attempted to write to switch {} that is SLAVE.", this.getId().toString()); + return ret; } } @@ -796,7 +895,7 @@ public class OFSwitch implements IOFSwitchBackend { @Override public <R extends OFMessage> ListenableFuture<R> writeRequest(OFRequest<R> request) { - return connections.get(OFAuxId.MAIN).writeRequest(request); + return writeRequest(request, LogicalOFMessageCategory.MAIN); } @Override diff --git a/src/main/java/net/floodlightcontroller/util/IterableUtils.java b/src/main/java/net/floodlightcontroller/util/IterableUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..d94d81160641de3c046741c9073245ce35552ff1 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/util/IterableUtils.java @@ -0,0 +1,28 @@ +package net.floodlightcontroller.util; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * Because it's handy. + * @author Ryan Izard, ryan.izard@bigswitch.com, rizard@g.clemson.edu + */ +public class IterableUtils { + + /** + * Convert an Iterable to a Collection (ArrayList under the hood). All items in the + * Iterable will be retained. + * @param i + * @return + */ + public static <T> Collection<T> toCollection(Iterable<T> i) { + if (i == null) { + throw new IllegalArgumentException("Iterable 'i' cannot be null"); + } + Collection<T> c = new ArrayList<T>(); + for (T t : i) { + c.add(t); + } + return c; + } +} \ No newline at end of file diff --git a/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java b/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java index 597ab8523b4ce1874d12495d3b4c8c61b5e4c035..ccf19f5b057e6f019803f8bab4a35e82bcda9317 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java +++ b/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java @@ -4,6 +4,8 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -72,13 +74,15 @@ public class MockOFConnection implements IOFConnectionBackend { } @Override - public void write(OFMessage m) { + public boolean write(OFMessage m) { messages.add(m); + return true; } @Override - public void write(Iterable<OFMessage> msglist) { + public Collection<OFMessage> write(Iterable<OFMessage> msglist) { Iterables.addAll(messages, msglist); + return Collections.emptyList(); } static class RequestAndFuture<R extends OFMessage> { diff --git a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchBaseTest.java b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchBaseTest.java index 8fefbfbf162c7dd51533f23b4e51ff36f229a627..5b73331d72a03219929a11244e205a13c15ae078 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchBaseTest.java +++ b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchBaseTest.java @@ -122,7 +122,7 @@ public class OFSwitchBaseTest { new PortChangeEvent(portBar1, PortChangeType.DELETE); private final PortChangeEvent portBar2Del = new PortChangeEvent(portBar2, PortChangeType.DELETE); - private Capture<OFMessage> capturedMessage; + private Capture<Iterable<OFMessage>> capturedMessage; private OFFactory factory; @Before @@ -144,9 +144,8 @@ public class OFSwitchBaseTest { .build(); IOFConnectionBackend conn = EasyMock.createNiceMock(IOFConnectionBackend.class); - capturedMessage = new Capture<OFMessage>(); - conn.write(EasyMock.capture(capturedMessage)); - expectLastCall().anyTimes(); + capturedMessage = new Capture<Iterable<OFMessage>>(); + expect(conn.write(EasyMock.capture(capturedMessage))).andReturn(Collections.<OFMessage>emptyList()).once(); expect(conn.getOFFactory()).andReturn(factory).anyTimes(); expect(conn.getAuxId()).andReturn(OFAuxId.MAIN).anyTimes(); EasyMock.replay(conn); @@ -154,6 +153,7 @@ public class OFSwitchBaseTest { IOFConnectionBackend auxConn = EasyMock.createNiceMock(IOFConnectionBackend.class); expect(auxConn.getOFFactory()).andReturn(factory).anyTimes(); expect(auxConn.getAuxId()).andReturn(OFAuxId.of(1)).anyTimes(); + expect(auxConn.write(EasyMock.capture(capturedMessage))).andReturn(Collections.<OFMessage>emptyList()).once(); EasyMock.replay(auxConn); sw = new OFSwitchTest(conn, switchManager); @@ -1405,9 +1405,9 @@ public class OFSwitchBaseTest { reset(switchManager); expect(switchManager.isCategoryRegistered(category)).andReturn(true); switchManager.handleOutgoingMessage(sw, testMessage); - expectLastCall(); + expectLastCall().once(); replay(switchManager); - + sw.write(testMessage, category); verify(switchManager); diff --git a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandlerTestBase.java b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandlerTestBase.java index 23cc4f12e661dc4043e9a85509464201179470e3..9f254d658bbe130ac27394707bd8fd619e825218 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandlerTestBase.java +++ b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandlerTestBase.java @@ -27,9 +27,11 @@ import java.util.concurrent.TimeUnit; import org.easymock.EasyMock; import org.hamcrest.CoreMatchers; import org.hamcrest.Matchers; + import io.netty.util.Timeout; import io.netty.util.Timer; import io.netty.util.TimerTask; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -521,10 +523,8 @@ public abstract class OFSwitchHandlerTestBase { // TODO: hmmm. While it's not incorrect that we set the attribute // again it looks odd. Maybe change expect(sw.getOFFactory()).andReturn(factory).anyTimes(); - sw.write(anyObject(OFMessage.class)); - expectLastCall().anyTimes(); - sw.write(anyObject(Iterable.class)); - expectLastCall().anyTimes(); + expect(sw.write(anyObject(OFMessage.class))).andReturn(true).anyTimes(); + expect(sw.write(anyObject(Iterable.class))).andReturn(Collections.EMPTY_LIST).anyTimes(); expect(sw.getNumTables()).andStubReturn((short)0); sw.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, supportsNxRole); expectLastCall().anyTimes(); @@ -599,10 +599,8 @@ public abstract class OFSwitchHandlerTestBase { // prepare mocks and inject the role reply message reset(sw); expect(sw.getOFFactory()).andReturn(factory).anyTimes(); - sw.write(anyObject(OFMessage.class)); - expectLastCall().anyTimes(); - sw.write(anyObject(Iterable.class)); - expectLastCall().anyTimes(); + expect(sw.write(anyObject(OFMessage.class))).andReturn(true).anyTimes(); + expect(sw.write(anyObject(Iterable.class))).andReturn(Collections.EMPTY_LIST).anyTimes(); expect(sw.getTables()).andStubReturn(Collections.EMPTY_LIST); expect(sw.getNumTables()).andStubReturn((short) 0); sw.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, true); @@ -695,10 +693,8 @@ public abstract class OFSwitchHandlerTestBase { // prepare mocks and inject the role reply message reset(sw); expect(sw.getOFFactory()).andReturn(factory).anyTimes(); - sw.write(anyObject(OFMessage.class)); - expectLastCall().anyTimes(); - sw.write(anyObject(Iterable.class)); - expectLastCall().anyTimes(); + expect(sw.write(anyObject(OFMessage.class))).andReturn(true).anyTimes(); + expect(sw.write(anyObject(Iterable.class))).andReturn(Collections.EMPTY_LIST).anyTimes(); expect(sw.getNumTables()).andStubReturn((short)0); sw.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, false); expectLastCall().once(); @@ -758,10 +754,8 @@ public abstract class OFSwitchHandlerTestBase { // prepare mocks and inject the role reply message reset(sw); expect(sw.getOFFactory()).andReturn(factory).anyTimes(); - sw.write(anyObject(OFMessage.class)); - expectLastCall().anyTimes(); - sw.write(anyObject(Iterable.class)); - expectLastCall().anyTimes(); + expect(sw.write(anyObject(OFMessage.class))).andReturn(true).anyTimes(); + expect(sw.write(anyObject(Iterable.class))).andReturn(Collections.EMPTY_LIST).anyTimes(); expect(sw.getNumTables()).andStubReturn((short)0); sw.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, false); expectLastCall().once(); @@ -922,10 +916,8 @@ public abstract class OFSwitchHandlerTestBase { // prepare mocks and inject the role reply message reset(sw); expect(sw.getOFFactory()).andReturn(factory).anyTimes(); - sw.write(anyObject(OFMessage.class)); - expectLastCall().anyTimes(); - sw.write(anyObject(Iterable.class)); - expectLastCall().anyTimes(); + expect(sw.write(anyObject(OFMessage.class))).andReturn(true).anyTimes(); + expect(sw.write(anyObject(Iterable.class))).andReturn(Collections.EMPTY_LIST).anyTimes(); expect(sw.getNumTables()).andStubReturn((short)0); sw.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, true); expectLastCall().once(); diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java index f3fc8c8ba05f35ff58207ad2e5074456030dc10d..fb1798028b835d52a8577b94ac736d25b1c2353d 100644 --- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java +++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java @@ -184,6 +184,9 @@ public class ForwardingTest extends FloodlightTestCase { expect(sw1.getSwitchDescription()).andReturn(new SwitchDescription(swDescription)).anyTimes(); expect(sw2.getSwitchDescription()).andReturn(new SwitchDescription(swDescription)).anyTimes(); + + expect(sw1.isActive()).andReturn(true).anyTimes(); + expect(sw2.isActive()).andReturn(true).anyTimes(); // Load the switch map Map<DatapathId, IOFSwitch> switches = new HashMap<DatapathId, IOFSwitch>(); @@ -457,10 +460,8 @@ public class ForwardingTest extends FloodlightTestCase { .build(); OFFlowMod fm2 = fm1.createBuilder().build(); - sw1.write(capture(wc1)); - expectLastCall().anyTimes(); - sw2.write(capture(wc2)); - expectLastCall().anyTimes(); + expect(sw1.write(capture(wc1))).andReturn(true).anyTimes(); + expect(sw2.write(capture(wc2))).andReturn(true).anyTimes(); reset(topology); expect(topology.getOpenflowDomainId(DatapathId.of(1L))).andReturn(DatapathId.of(1L)).anyTimes(); @@ -529,10 +530,8 @@ public class ForwardingTest extends FloodlightTestCase { .build(); OFFlowMod fm2 = fm1.createBuilder().build(); - sw1.write(capture(wc1)); - expectLastCall().anyTimes(); - sw2.write(capture(wc2)); - expectLastCall().anyTimes(); + expect(sw1.write(capture(wc1))).andReturn(true).anyTimes(); + expect(sw2.write(capture(wc2))).andReturn(true).anyTimes(); reset(topology); expect(topology.getOpenflowDomainId(DatapathId.of(1L))).andReturn(DatapathId.of(1L)).anyTimes(); @@ -597,10 +596,8 @@ public class ForwardingTest extends FloodlightTestCase { .build(); // Record expected packet-outs/flow-mods - sw1.write(capture(wc1)); - expectLastCall().once(); - sw1.write(capture(wc2)); - expectLastCall().once(); + expect(sw1.write(capture(wc1))).andReturn(true).once(); + expect(sw1.write(capture(wc2))).andReturn(true).once(); reset(topology); expect(topology.isIncomingBroadcastAllowed(DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(true).anyTimes(); @@ -653,10 +650,8 @@ public class ForwardingTest extends FloodlightTestCase { .build(); // Record expected packet-outs/flow-mods - sw1.write(capture(wc1)); - expectLastCall().once(); - sw1.write(capture(wc2)); - expectLastCall().once(); + expect(sw1.write(capture(wc1))).andReturn(true).once(); + expect(sw1.write(capture(wc2))).andReturn(true).once(); reset(topology); expect(topology.isIncomingBroadcastAllowed(DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(true).anyTimes(); @@ -758,8 +753,7 @@ public class ForwardingTest extends FloodlightTestCase { .andReturn(true) .anyTimes(); expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_FLOOD)).andReturn(true).anyTimes(); - sw1.write(capture(wc1)); - expectLastCall().once(); + expect(sw1.write(capture(wc1))).andReturn(true).once(); replay(sw1, sw2, routingEngine, topology); forwarding.receive(sw1, this.packetIn, cntx); verify(sw1, sw2, routingEngine); @@ -792,8 +786,7 @@ public class ForwardingTest extends FloodlightTestCase { expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_FLOOD)) .andReturn(true).anyTimes(); // Reset XID to expected (dependent on prior unit tests) - sw1.write(capture(wc1)); - expectLastCall().once(); + expect(sw1.write(capture(wc1))).andReturn(true).once(); replay(sw1, sw2, routingEngine, topology); forwarding.receive(sw1, this.packetInIPv6, cntx); verify(sw1, sw2, routingEngine); diff --git a/src/test/java/net/floodlightcontroller/hub/HubTest.java b/src/test/java/net/floodlightcontroller/hub/HubTest.java index 6a0a2dde83c80d9baf104afed0b176f3a00d546c..6bc1c98984d123ef3342de16dac4021bfca7a263 100644 --- a/src/test/java/net/floodlightcontroller/hub/HubTest.java +++ b/src/test/java/net/floodlightcontroller/hub/HubTest.java @@ -19,6 +19,7 @@ package net.floodlightcontroller.hub; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.verify; import static org.easymock.EasyMock.capture; import static org.junit.Assert.*; @@ -122,7 +123,7 @@ public class HubTest extends FloodlightTestCase { Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL); - mockSwitch.write(capture(wc1)); + expect(mockSwitch.write(capture(wc1))).andReturn(true).anyTimes(); // Start recording the replay on the mocks replay(mockSwitch); @@ -163,7 +164,7 @@ public class HubTest extends FloodlightTestCase { IOFSwitch mockSwitch = createMock(IOFSwitch.class); EasyMock.expect(mockSwitch.getOFFactory()).andReturn(OFFactories.getFactory(OFVersion.OF_13)).anyTimes(); Capture<OFPacketOut> wc1 = new Capture<OFPacketOut>(CaptureType.ALL); - mockSwitch.write(capture(wc1)); + expect(mockSwitch.write(capture(wc1))).andReturn(true).anyTimes(); // Start recording the replay on the mocks replay(mockSwitch); diff --git a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java index b2754b2ea73b0b14743c7432648c45c5c7655aae..fd397c461a006fb0ce65d9854977a633fbc8fca8 100644 --- a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java +++ b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java @@ -190,8 +190,7 @@ public class LearningSwitchTest extends FloodlightTestCase { IOFSwitch mockSwitch = createMock(IOFSwitch.class); expect(mockSwitch.getId()).andReturn(DatapathId.of("00:11:22:33:44:55:66:77")).anyTimes(); expect(mockSwitch.getOFFactory()).andReturn(factory).anyTimes(); - mockSwitch.write(EasyMock.capture(wc1)); // expect po - EasyMock.expectLastCall().once(); + expect(mockSwitch.write(EasyMock.capture(wc1))).andReturn(true).once(); // expect po // Start recording the replay on the mocks replay(mockSwitch); @@ -269,12 +268,9 @@ public class LearningSwitchTest extends FloodlightTestCase { expect(mockSwitch.getBuffers()).andReturn((long)100).anyTimes(); expect(mockSwitch.getOFFactory()).andReturn(factory).anyTimes(); - mockSwitch.write(EasyMock.capture(wc1)); // expect packetOut - EasyMock.expectLastCall().once(); - mockSwitch.write(EasyMock.capture(wc2)); // expect fm1 - EasyMock.expectLastCall().once(); - mockSwitch.write(EasyMock.capture(wc3)); // expect fm2 - EasyMock.expectLastCall().once(); + expect(mockSwitch.write(EasyMock.capture(wc1))).andReturn(true).once(); // expect packetOut + expect(mockSwitch.write(EasyMock.capture(wc2))).andReturn(true).once(); // expect fm1 + expect(mockSwitch.write(EasyMock.capture(wc3))).andReturn(true).once(); // expect fm2 // Start recording the replay on the mocks replay(mockSwitch); diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java index a4c8d244785fcccf952d5db5133bd7e01e72264f..89638f378e66be3bb5c21d6ea7b95629ff7416e1 100644 --- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java +++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java @@ -21,7 +21,6 @@ import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import static org.junit.Assert.*; @@ -497,8 +496,7 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase { expect(sw1.getPort(OFPort.of(EasyMock.anyInt()))).andReturn(ofpp).anyTimes(); expect(sw1.getOFFactory()).andReturn(OFFactories.getFactory(OFVersion.OF_13)).anyTimes(); expect(sw1.getLatency()).andReturn(U64.ZERO).anyTimes(); - sw1.write(capture(wc)); - expectLastCall().anyTimes(); + expect(sw1.write(capture(wc))).andReturn(true).anyTimes(); replay(sw1); linkDiscovery.switchActivated(sw1.getId()); diff --git a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java index b12b2f5cdc8adca998f20e319c4712164968b248..f8c0101af6b2b5e534f232c0f566d4984756d858 100644 --- a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java +++ b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java @@ -446,8 +446,7 @@ public class LoadBalancerTest extends FloodlightTestCase { expect(sw1.getId()).andReturn(DatapathId.of(1L)).anyTimes(); expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes(); expect(sw1.getOFFactory()).andReturn(factory).anyTimes(); - sw1.write(capture(wc1)); - expectLastCall().anyTimes(); + expect(sw1.write(capture(wc1))).andReturn(true).anyTimes(); replay(sw1); sfp.switchAdded(DatapathId.of(1L)); diff --git a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java index 407db1d3c70d6c25ea458460983eec0811329195..25f8f4ea1ade6578f2ee1361f641f1ded33d3fdb 100644 --- a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java +++ b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java @@ -203,10 +203,8 @@ public class StaticFlowTests extends FloodlightTestCase { writeCapture = new Capture<OFMessage>(CaptureType.ALL); writeCaptureList = new Capture<List<OFMessage>>(CaptureType.ALL); - mockSwitch.write(capture(writeCapture)); - expectLastCall().anyTimes(); - mockSwitch.write(capture(writeCaptureList)); - expectLastCall().anyTimes(); + expect(mockSwitch.write(capture(writeCapture))).andReturn(true).anyTimes(); + expect(mockSwitch.write(capture(writeCaptureList))).andReturn(Collections.<OFMessage>emptyList()).anyTimes(); expect(mockSwitch.getOFFactory()).andReturn(factory).anyTimes(); replay(mockSwitch); @@ -247,10 +245,8 @@ public class StaticFlowTests extends FloodlightTestCase { // if someone calls getId(), return this dpid instead resetToNice(mockSwitch); - mockSwitch.write(capture(writeCapture)); - expectLastCall().anyTimes(); - mockSwitch.write(capture(writeCaptureList)); - expectLastCall().anyTimes(); + expect(mockSwitch.write(capture(writeCapture))).andReturn(true).anyTimes(); + expect(mockSwitch.write(capture(writeCaptureList))).andReturn(Collections.<OFMessage> emptyList()).anyTimes(); expect(mockSwitch.getOFFactory()).andReturn(factory).anyTimes(); expect(mockSwitch.getId()).andReturn(DatapathId.of(dpid)).anyTimes(); replay(mockSwitch); diff --git a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java index ca5d326569d59c60891e312f46cf878cd28632a0..39569240cc8603be553fd5507e638d889a5c3429 100644 --- a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java +++ b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java @@ -20,6 +20,7 @@ import static org.junit.Assert.*; import java.net.SocketAddress; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -203,14 +204,14 @@ public class OFMessageDamperMockSwitch implements IOFSwitch { } @Override - public void write(OFMessage m) { + public boolean write(OFMessage m) { writtenMessage = m; - // TODO Auto-generated method stub + return true; } @Override - public void write(Iterable<OFMessage> msglist) { - // TODO Auto-generated method stub + public Collection<OFMessage> write(Iterable<OFMessage> msgList) { + return Collections.emptyList(); } @Override @@ -282,16 +283,14 @@ public class OFMessageDamperMockSwitch implements IOFSwitch { } @Override - public void write(OFMessage m, LogicalOFMessageCategory category) { - // TODO Auto-generated method stub - + public boolean write(OFMessage m, LogicalOFMessageCategory category) { + return true; } @Override - public void write(Iterable<OFMessage> msglist, + public Collection<OFMessage> write(Iterable<OFMessage> msgList, LogicalOFMessageCategory category) { - // TODO Auto-generated method stub - + return Collections.emptyList(); } @Override