diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java index 177c46dbb5bcd534d8f4426b4a24a0be012c5d44..a4ee23073aa462db36295c529a48ffebee16519d 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java +++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -45,6 +46,7 @@ import net.floodlightcontroller.core.internal.Controller.IUpdate; import net.floodlightcontroller.core.internal.Controller.SwitchUpdate; import net.floodlightcontroller.core.internal.Controller.SwitchUpdateType; import net.floodlightcontroller.core.internal.OFChannelState.HandshakeState; +import net.floodlightcontroller.core.internal.RoleChanger.PendingRoleRequestEntry; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.test.MockFloodlightProvider; import net.floodlightcontroller.core.test.MockThreadPoolService; @@ -71,6 +73,7 @@ import org.openflow.protocol.OFError; import org.openflow.protocol.OFError.OFBadRequestCode; import org.openflow.protocol.OFError.OFErrorType; import org.openflow.protocol.OFFeaturesReply; +import org.openflow.protocol.OFMessage; import org.openflow.protocol.OFPacketIn; import org.openflow.protocol.OFPacketOut; import org.openflow.protocol.OFPhysicalPort; @@ -88,9 +91,12 @@ import org.openflow.protocol.statistics.OFDescriptionStatistics; import org.openflow.protocol.statistics.OFFlowStatisticsReply; import org.openflow.protocol.statistics.OFStatistics; import org.openflow.protocol.statistics.OFStatisticsType; +import org.openflow.protocol.vendor.OFVendorData; import org.openflow.util.HexString; import org.openflow.vendor.nicira.OFNiciraVendorData; import org.openflow.vendor.nicira.OFRoleReplyVendorData; +import org.openflow.vendor.nicira.OFRoleRequestVendorData; +import org.openflow.vendor.nicira.OFRoleVendorData; /** * @@ -996,11 +1002,9 @@ public class ControllerTest extends FloodlightTestCase // in SLAVE mode and the switch does not support role-request messages state.firstRoleReplyReceived = false; controller.role = Role.SLAVE; - expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true); - chdlr.sw.deliverRoleRequestNotSupported(xid); - expect(chdlr.sw.getChannel()).andReturn(ch).anyTimes(); - expect(chdlr.sw.getRole()).andReturn(null).anyTimes(); - expect(ch.close()).andReturn(null); + setupPendingRoleRequest(chdlr.sw, xid, controller.role, 123456); + chdlr.sw.setHARole(Role.SLAVE, false); + chdlr.sw.disconnectOutputStream(); replay(ch, chdlr.sw); chdlr.processOFMessage(msg); @@ -1017,11 +1021,9 @@ public class ControllerTest extends FloodlightTestCase msg.setErrorCode(OFBadRequestCode.OFPBRC_EPERM); state.firstRoleReplyReceived = false; controller.role = Role.SLAVE; - expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true); - chdlr.sw.deliverRoleRequestNotSupported(xid); - expect(chdlr.sw.getChannel()).andReturn(ch).anyTimes(); - expect(chdlr.sw.getRole()).andReturn(null).anyTimes(); - expect(ch.close()).andReturn(null); + setupPendingRoleRequest(chdlr.sw, xid, controller.role, 123456); + chdlr.sw.setHARole(Role.SLAVE, false); + chdlr.sw.disconnectOutputStream(); replay(ch, chdlr.sw); chdlr.processOFMessage(msg); @@ -1037,8 +1039,8 @@ public class ControllerTest extends FloodlightTestCase // switches. state.firstRoleReplyReceived = false; controller.role = Role.MASTER; - expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true); - chdlr.sw.deliverRoleRequestNotSupported(xid); + setupPendingRoleRequest(chdlr.sw, xid, controller.role, 123456); + chdlr.sw.setHARole(controller.role, false); setupSwitchForAddSwitch(chdlr.sw, 0L); chdlr.sw.clearAllFlowMods(); expect(chdlr.sw.getRole()).andReturn(null).anyTimes(); @@ -1087,7 +1089,18 @@ public class ControllerTest extends FloodlightTestCase roleReplyVendorData.setRole(nicira_role); return msg; } - + + // Helper function + protected void setupPendingRoleRequest(IOFSwitch sw, int xid, Role role, + long cookie) { + LinkedList<PendingRoleRequestEntry> pendingList = + new LinkedList<PendingRoleRequestEntry>(); + controller.roleChanger.pendingRequestMap.put(sw, pendingList); + PendingRoleRequestEntry entry = + new PendingRoleRequestEntry(xid, role, cookie); + pendingList.add(entry); + } + /** invalid role in role reply */ @Test public void testNiciraRoleReplyInvalidRole() @@ -1111,8 +1124,9 @@ public class ControllerTest extends FloodlightTestCase Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest(); OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, OFRoleReplyVendorData.NX_ROLE_MASTER); - - chdlr.sw.deliverRoleReply(xid, Role.MASTER); + + setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456); + chdlr.sw.setHARole(Role.MASTER, true); expect(chdlr.sw.isActive()).andReturn(true); setupSwitchForAddSwitch(chdlr.sw, 1L); chdlr.sw.clearAllFlowMods(); @@ -1135,8 +1149,9 @@ public class ControllerTest extends FloodlightTestCase Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest(); OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, OFRoleReplyVendorData.NX_ROLE_MASTER); - - chdlr.sw.deliverRoleReply(xid, Role.MASTER); + + setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456); + chdlr.sw.setHARole(Role.MASTER, true); expect(chdlr.sw.isActive()).andReturn(true); setupSwitchForAddSwitch(chdlr.sw, 1L); chdlr.state.firstRoleReplyReceived = true; @@ -1159,7 +1174,8 @@ public class ControllerTest extends FloodlightTestCase OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, OFRoleReplyVendorData.NX_ROLE_OTHER); - chdlr.sw.deliverRoleReply(xid, Role.EQUAL); + setupPendingRoleRequest(chdlr.sw, xid, Role.EQUAL, 123456); + chdlr.sw.setHARole(Role.EQUAL, true); expect(chdlr.sw.isActive()).andReturn(true); setupSwitchForAddSwitch(chdlr.sw, 1L); chdlr.sw.clearAllFlowMods(); @@ -1181,7 +1197,8 @@ public class ControllerTest extends FloodlightTestCase OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, OFRoleReplyVendorData.NX_ROLE_SLAVE); - chdlr.sw.deliverRoleReply(xid, Role.SLAVE); + setupPendingRoleRequest(chdlr.sw, xid, Role.SLAVE, 123456); + chdlr.sw.setHARole(Role.SLAVE, true); expect(chdlr.sw.getId()).andReturn(1L).anyTimes(); expect(chdlr.sw.getStringId()).andReturn("00:00:00:00:00:00:00:01") .anyTimes(); @@ -1205,7 +1222,8 @@ public class ControllerTest extends FloodlightTestCase OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, OFRoleReplyVendorData.NX_ROLE_MASTER); - chdlr.sw.deliverRoleReply(xid, Role.MASTER); + setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456); + chdlr.sw.setHARole(Role.MASTER, true); expect(chdlr.sw.getId()).andReturn(1L).anyTimes(); expect(chdlr.sw.getStringId()).andReturn("00:00:00:00:00:00:00:01") .anyTimes(); @@ -1230,7 +1248,8 @@ public class ControllerTest extends FloodlightTestCase OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, OFRoleReplyVendorData.NX_ROLE_SLAVE); - chdlr.sw.deliverRoleReply(xid, Role.SLAVE); + setupPendingRoleRequest(chdlr.sw, xid, Role.SLAVE, 123456); + chdlr.sw.setHARole(Role.SLAVE, true); expect(chdlr.sw.getId()).andReturn(1L).anyTimes(); expect(chdlr.sw.getStringId()).andReturn("00:00:00:00:00:00:00:01") .anyTimes(); @@ -1331,4 +1350,43 @@ public class ControllerTest extends FloodlightTestCase } return null; } + + public void doSendNxRoleRequest(Role role, int nx_role) throws Exception { + long cookie = System.nanoTime(); + OFSwitchImpl sw = new OFSwitchImpl(); + Channel ch = createMock(Channel.class); + sw.setChannel(ch); + sw.setFloodlightProvider(controller); + + // verify that the correct OFMessage is sent + Capture<List<OFMessage>> msgCapture = new Capture<List<OFMessage>>(); + expect(sw.channel.write(capture(msgCapture))).andReturn(null); + replay(sw.channel); + int xid = sw.sendHARoleRequest(role, cookie); + verify(sw.channel); + List<OFMessage> msgList = msgCapture.getValue(); + assertEquals(1, msgList.size()); + OFMessage msg = msgList.get(0); + assertEquals("Transaction Ids must match", xid, msg.getXid()); + assertTrue("Message must be an OFVendor type", msg instanceof OFVendor); + assertEquals(OFType.VENDOR, msg.getType()); + OFVendor vendorMsg = (OFVendor)msg; + assertEquals("Vendor message must be vendor Nicira", + OFNiciraVendorData.NX_VENDOR_ID, vendorMsg.getVendor()); + OFVendorData vendorData = vendorMsg.getVendorData(); + assertTrue("Vendor Data must be an OFRoleRequestVendorData", + vendorData instanceof OFRoleRequestVendorData); + OFRoleRequestVendorData roleRequest = (OFRoleRequestVendorData)vendorData; + assertEquals(nx_role, roleRequest.getRole()); + + reset(sw.channel); + } + + @Test + public void testSendNxRoleRequest() throws Exception { + doSendNxRoleRequest(Role.MASTER, OFRoleVendorData.NX_ROLE_MASTER); + doSendNxRoleRequest(Role.SLAVE, OFRoleVendorData.NX_ROLE_SLAVE); + doSendNxRoleRequest(Role.EQUAL, OFRoleVendorData.NX_ROLE_OTHER); + } + } diff --git a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java index f70e56579715a7d5551311a85664035575330b07..fafcf28cc6fc6c082b4a56147fbf221119692246 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java +++ b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java @@ -1,27 +1,18 @@ package net.floodlightcontroller.core.internal; import static org.easymock.EasyMock.*; +import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; -import java.util.List; - -import net.floodlightcontroller.core.IFloodlightProviderService.Role; +import net.floodlightcontroller.core.HARoleUnsupportedException; import net.floodlightcontroller.core.IOFSwitch; -import net.floodlightcontroller.core.internal.OFSwitchImpl.PendingRoleRequestEntry; +import net.floodlightcontroller.core.IFloodlightProviderService.Role; import net.floodlightcontroller.core.test.MockFloodlightProvider; import net.floodlightcontroller.test.FloodlightTestCase; -import org.easymock.Capture; import org.jboss.netty.channel.Channel; import org.junit.Before; import org.junit.Test; -import org.openflow.protocol.OFMessage; -import org.openflow.protocol.OFType; -import org.openflow.protocol.OFVendor; -import org.openflow.protocol.vendor.OFVendorData; -import org.openflow.vendor.nicira.OFNiciraVendorData; -import org.openflow.vendor.nicira.OFRoleRequestVendorData; -import org.openflow.vendor.nicira.OFRoleVendorData; public class OFSwitchImplTest extends FloodlightTestCase { protected OFSwitchImpl sw; @@ -36,201 +27,87 @@ public class OFSwitchImplTest extends FloodlightTestCase { sw.setChannel(ch); MockFloodlightProvider floodlightProvider = new MockFloodlightProvider(); sw.setFloodlightProvider(floodlightProvider); - } - - - public void doSendNxRoleRequest(Role role, int nx_role) throws Exception { - long cookie = System.nanoTime(); - - // verify that the correct OFMessage is sent - Capture<List<OFMessage>> msgCapture = new Capture<List<OFMessage>>(); - expect(sw.channel.write(capture(msgCapture))).andReturn(null); - replay(sw.channel); - int xid = sw.sendHARoleRequest(role, cookie); - verify(sw.channel); - List<OFMessage> msgList = msgCapture.getValue(); - assertEquals(1, msgList.size()); - OFMessage msg = msgList.get(0); - assertEquals("Transaction Ids must match", xid, msg.getXid()); - assertTrue("Message must be an OFVendor type", msg instanceof OFVendor); - assertEquals(OFType.VENDOR, msg.getType()); - OFVendor vendorMsg = (OFVendor)msg; - assertEquals("Vendor message must be vendor Nicira", - OFNiciraVendorData.NX_VENDOR_ID, vendorMsg.getVendor()); - OFVendorData vendorData = vendorMsg.getVendorData(); - assertTrue("Vendor Data must be an OFRoleRequestVendorData", - vendorData instanceof OFRoleRequestVendorData); - OFRoleRequestVendorData roleRequest = (OFRoleRequestVendorData)vendorData; - assertEquals(nx_role, roleRequest.getRole()); - - // Now verify that we've added the pending request correctly - // to the pending queue - assertEquals(1, sw.pendingRoleRequests.size()); - PendingRoleRequestEntry pendingRoleRequest = sw.pendingRoleRequests.poll(); - assertEquals(msg.getXid(), pendingRoleRequest.xid); - assertEquals(role, pendingRoleRequest.role); - assertEquals(cookie, pendingRoleRequest.cookie); - reset(sw.channel); - } + } @Test - public void testSendNxRoleRequest() throws Exception { - doSendNxRoleRequest(Role.MASTER, OFRoleVendorData.NX_ROLE_MASTER); - doSendNxRoleRequest(Role.SLAVE, OFRoleVendorData.NX_ROLE_SLAVE); - doSendNxRoleRequest(Role.EQUAL, OFRoleVendorData.NX_ROLE_OTHER); + public void testSendHARoleRequestFirstTime() { + boolean ioExceptionCaught = false; + boolean unsupportedExceptionCaught = false; + try { + sw.sendHARoleRequest(Role.MASTER, 12355); + } catch (IOException e) { + ioExceptionCaught = true; + } catch (HARoleUnsupportedException e) { + unsupportedExceptionCaught = true; + } + assertEquals(false, ioExceptionCaught); + assertEquals(false, unsupportedExceptionCaught); } - @Test - public void testDeliverRoleReplyOk() { - // test normal case - PendingRoleRequestEntry pending = new PendingRoleRequestEntry( - (int)System.currentTimeMillis(), // arbitrary xid - Role.MASTER, - System.nanoTime() // arbitrary cookie - ); - sw.pendingRoleRequests.add(pending); - replay(sw.channel); - sw.deliverRoleReply(pending.xid, pending.role); - verify(sw.channel); - assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); - assertEquals(pending.role, sw.role); - assertEquals(0, sw.pendingRoleRequests.size()); + public void testSendHARoleRequestSecondTime() { + boolean ioExceptionCaught = false; + boolean unsupportedExceptionCaught = false; + try { + sw.setHARole(Role.EQUAL, true); + sw.sendHARoleRequest(Role.MASTER, 12355); + } catch (IOException e) { + ioExceptionCaught = true; + } catch (HARoleUnsupportedException e) { + unsupportedExceptionCaught = true; + } + assertEquals(false, ioExceptionCaught); + assertEquals(false, unsupportedExceptionCaught); } @Test - public void testDeliverRoleReplyOkRepeated() { - // test normal case. Not the first role reply - PendingRoleRequestEntry pending = new PendingRoleRequestEntry( - (int)System.currentTimeMillis(), // arbitrary xid - Role.MASTER, - System.nanoTime() // arbitrary cookie - ); - sw.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, true); - sw.pendingRoleRequests.add(pending); - replay(sw.channel); - sw.deliverRoleReply(pending.xid, pending.role); - verify(sw.channel); - assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); - assertEquals(pending.role, sw.role); - assertEquals(0, sw.pendingRoleRequests.size()); + public void testSendHARoleRequestUnsupported() { + boolean ioExceptionCaught = false; + boolean unsupportedExceptionCaught = false; + try { + sw.setHARole(Role.EQUAL, false); + sw.sendHARoleRequest(Role.MASTER, 12355); + } catch (IOException e) { + ioExceptionCaught = true; + } catch (HARoleUnsupportedException e) { + unsupportedExceptionCaught = true; + } + assertEquals(false, ioExceptionCaught); + assertEquals(true, unsupportedExceptionCaught); } @Test - public void testDeliverRoleReplyNonePending() { - // nothing pending - expect(sw.channel.close()).andReturn(null); - replay(sw.channel); - sw.deliverRoleReply(1, Role.MASTER); - verify(sw.channel); - assertEquals(0, sw.pendingRoleRequests.size()); - } - - @Test - public void testDeliverRoleReplyWrongXid() { - // wrong xid received - PendingRoleRequestEntry pending = new PendingRoleRequestEntry( - (int)System.currentTimeMillis(), // arbitrary xid - Role.MASTER, - System.nanoTime() // arbitrary cookie - ); - sw.pendingRoleRequests.add(pending); - expect(sw.channel.close()).andReturn(null); - replay(sw.channel); - sw.deliverRoleReply(pending.xid+1, pending.role); - verify(sw.channel); + public void testSetHARoleReplyReceived() { assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); - assertEquals(0, sw.pendingRoleRequests.size()); + + sw.setHARole(Role.MASTER, true); + assertEquals(Role.MASTER, sw.role); + assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); + + sw.setHARole(Role.EQUAL, true); + assertEquals(Role.EQUAL, sw.role); + assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); + + sw.setHARole(Role.SLAVE, true); + assertEquals(Role.SLAVE, sw.role); + assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); } @Test - public void testDeliverRoleReplyWrongRole() { - // correct xid but incorrect role received - PendingRoleRequestEntry pending = new PendingRoleRequestEntry( - (int)System.currentTimeMillis(), // arbitrary xid - Role.MASTER, - System.nanoTime() // arbitrary cookie - ); - sw.pendingRoleRequests.add(pending); - expect(sw.channel.close()).andReturn(null); - replay(sw.channel); - sw.deliverRoleReply(pending.xid, Role.SLAVE); - verify(sw.channel); + public void testSetHARoleNoReply() { assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); - assertEquals(0, sw.pendingRoleRequests.size()); - } - - @Test - public void testCheckFirstPendingRoleRequestXid() { - PendingRoleRequestEntry pending = new PendingRoleRequestEntry( - 54321, Role.MASTER, 232323); - replay(sw.channel); // we don't expect any invocations - sw.pendingRoleRequests.add(pending); - assertEquals(true, sw.checkFirstPendingRoleRequestXid(54321)); - assertEquals(false, sw.checkFirstPendingRoleRequestXid(0)); - sw.pendingRoleRequests.clear(); - assertEquals(false, sw.checkFirstPendingRoleRequestXid(54321)); - verify(sw.channel); - } - - @Test - public void testCheckFirstPendingRoleRequestCookie() { - PendingRoleRequestEntry pending = new PendingRoleRequestEntry( - 54321, Role.MASTER, 232323); - replay(sw.channel); // we don't expect any invocations - sw.pendingRoleRequests.add(pending); - assertEquals(true, sw.checkFirstPendingRoleRequestCookie(232323)); - assertEquals(false, sw.checkFirstPendingRoleRequestCookie(0)); - sw.pendingRoleRequests.clear(); - assertEquals(false, sw.checkFirstPendingRoleRequestCookie(232323)); - verify(sw.channel); - } - - @Test - public void testDeliverRoleRequestNotSupported () { - // normal case. xid is pending - PendingRoleRequestEntry pending = new PendingRoleRequestEntry( - (int)System.currentTimeMillis(), // arbitrary xid - Role.MASTER, - System.nanoTime() // arbitrary cookie - ); - sw.role = Role.SLAVE; - sw.pendingRoleRequests.add(pending); - replay(sw.channel); - sw.deliverRoleRequestNotSupported(pending.xid); - verify(sw.channel); + + sw.setHARole(Role.MASTER, false); + assertEquals(Role.MASTER, sw.role); + assertEquals(false, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); + + sw.setHARole(Role.EQUAL, false); + assertEquals(Role.EQUAL, sw.role); + assertEquals(false, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); + + sw.setHARole(Role.SLAVE, false); + assertEquals(Role.SLAVE, sw.role); assertEquals(false, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); - assertEquals(null, sw.role); - assertEquals(0, sw.pendingRoleRequests.size()); - } - - @Test - public void testDeliverRoleRequestNotSupportedNonePending() { - // nothing pending - sw.role = Role.SLAVE; - expect(sw.channel.close()).andReturn(null); - replay(sw.channel); - sw.deliverRoleRequestNotSupported(1); - verify(sw.channel); - assertEquals(null, sw.role); - assertEquals(0, sw.pendingRoleRequests.size()); - } - - @Test - public void testDeliverRoleRequestNotSupportedWrongXid() { - // wrong xid received - PendingRoleRequestEntry pending = new PendingRoleRequestEntry( - (int)System.currentTimeMillis(), // arbitrary xid - Role.MASTER, - System.nanoTime() // arbitrary cookie - ); - sw.role = Role.SLAVE; - sw.pendingRoleRequests.add(pending); - expect(sw.channel.close()).andReturn(null); - replay(sw.channel); - sw.deliverRoleRequestNotSupported(pending.xid+1); - verify(sw.channel); - assertEquals(null, sw.role); - assertEquals(0, sw.pendingRoleRequests.size()); } + } diff --git a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java index 76ea85d58b74a8c62138988496e3f3de069303f9..0b068824bfb4a8d1a33f14848c4afda4521a6877 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java +++ b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java @@ -7,10 +7,15 @@ import static org.easymock.EasyMock.verify; import static org.junit.Assert.*; import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.util.Collection; import java.util.LinkedList; + +import net.floodlightcontroller.core.HARoleUnsupportedException; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IFloodlightProviderService.Role; +import net.floodlightcontroller.core.internal.RoleChanger.PendingRoleRequestEntry; import net.floodlightcontroller.core.internal.RoleChanger.RoleChangeTask; import org.easymock.EasyMock; @@ -31,7 +36,7 @@ public class RoleChangerTest { * The connection should be closed. */ @Test - public void testSendRoleRequestSlaveNotSupported() { + public void testSendRoleRequestSlaveNotSupported() throws Exception { LinkedList<IOFSwitch> switches = new LinkedList<IOFSwitch>(); // a switch that doesn't support role requests @@ -39,8 +44,8 @@ public class RoleChangerTest { Channel channel1 = createMock(Channel.class); expect(sw1.getChannel()).andReturn(channel1); // No support for NX_ROLE - expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)) - .andReturn(false); + expect(sw1.sendHARoleRequest(Role.SLAVE, 123456)) + .andThrow(new HARoleUnsupportedException()).once();; expect(channel1.close()).andReturn(null); switches.add(sw1); @@ -58,14 +63,14 @@ public class RoleChangerTest { * The connection should be closed. */ @Test - public void testSendRoleRequestMasterNotSupported() { + public void testSendRoleRequestMasterNotSupported() throws Exception { LinkedList<IOFSwitch> switches = new LinkedList<IOFSwitch>(); // a switch that doesn't support role requests OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class); // No support for NX_ROLE - expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)) - .andReturn(false); + expect(sw1.sendHARoleRequest(Role.MASTER, 123456)) + .andThrow(new HARoleUnsupportedException()).once();; switches.add(sw1); replay(sw1); @@ -86,8 +91,6 @@ public class RoleChangerTest { // a switch that supports role requests OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class); // No support for NX_ROLE - expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)) - .andReturn(true); expect(sw1.sendHARoleRequest(Role.MASTER, 123456)) .andThrow(new IOException()).once(); Channel channel1 = createMock(Channel.class); @@ -112,20 +115,15 @@ public class RoleChangerTest { // a switch that supports role requests OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class); - // No support for NX_ROLE - expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)) - .andReturn(true); + // Support for NX_ROLE expect(sw1.sendHARoleRequest(Role.MASTER, 123456)).andReturn(1).once(); switches.add(sw1); - // a switch for which we don't have SUPPORTS_NX_ROLE yet + // second switch OFSwitchImpl sw2 = EasyMock.createMock(OFSwitchImpl.class); - // No support for NX_ROLE - expect(sw2.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)) - .andReturn(null); + // Support for NX_ROLE expect(sw2.sendHARoleRequest(Role.MASTER, 123456)).andReturn(1).once(); - switches.add(sw2); - + switches.add(sw2); replay(sw1, sw2); roleChanger.sendRoleRequest(switches, Role.MASTER, 123456); @@ -135,22 +133,27 @@ public class RoleChangerTest { } @Test - public void testVerifyRoleReplyReceived() { + public void testVerifyRoleReplyReceived() throws Exception { Collection<IOFSwitch> switches = new LinkedList<IOFSwitch>(); // Add a switch that has received a role reply OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class); - expect(sw1.checkFirstPendingRoleRequestCookie(123456)) - .andReturn(false).once(); + LinkedList<PendingRoleRequestEntry> pendingList1 = + new LinkedList<PendingRoleRequestEntry>(); + roleChanger.pendingRequestMap.put(sw1, pendingList1); switches.add(sw1); // Add a switch that has not yet received a role reply OFSwitchImpl sw2 = EasyMock.createMock(OFSwitchImpl.class); - expect(sw2.checkFirstPendingRoleRequestCookie(123456)) - .andReturn(true).once(); - Channel channel2 = createMock(Channel.class); - expect(sw2.getChannel()).andReturn(channel2); - expect(channel2.close()).andReturn(null); + LinkedList<PendingRoleRequestEntry> pendingList2 = + new LinkedList<PendingRoleRequestEntry>(); + roleChanger.pendingRequestMap.put(sw2, pendingList2); + PendingRoleRequestEntry entry = + new PendingRoleRequestEntry(1, Role.MASTER, 123456); + pendingList2.add(entry); + // Timed out switch should disconnect + sw2.setHARole(null, false); + EasyMock.expectLastCall(); switches.add(sw2); @@ -191,20 +194,11 @@ public class RoleChangerTest { // a switch that supports role requests OFSwitchImpl sw1 = EasyMock.createStrictMock(OFSwitchImpl.class); - // No support for NX_ROLE - expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)) - .andReturn(true); + // Support for NX_ROLE expect(sw1.sendHARoleRequest(EasyMock.same(Role.MASTER), EasyMock.anyLong())) .andReturn(1); - expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)) - .andReturn(true); expect(sw1.sendHARoleRequest(EasyMock.same(Role.SLAVE), EasyMock.anyLong())) .andReturn(1); - // The following calls happen for timeout handling: - expect(sw1.checkFirstPendingRoleRequestCookie(EasyMock.anyLong())) - .andReturn(false); - expect(sw1.checkFirstPendingRoleRequestCookie(EasyMock.anyLong())) - .andReturn(false); switches.add(sw1); @@ -230,4 +224,176 @@ public class RoleChangerTest { } + // Helper function + protected void setupPendingRoleRequest(IOFSwitch sw, int xid, Role role, + long cookie) { + LinkedList<PendingRoleRequestEntry> pendingList = + new LinkedList<PendingRoleRequestEntry>(); + roleChanger.pendingRequestMap.put(sw, pendingList); + PendingRoleRequestEntry entry = + new PendingRoleRequestEntry(xid, role, cookie); + pendingList.add(entry); + } + + + @Test + public void testDeliverRoleReplyOk() { + // test normal case + int xid = (int) System.currentTimeMillis(); + long cookie = System.nanoTime(); + Role role = Role.MASTER; + OFSwitchImpl sw = new OFSwitchImpl(); + setupPendingRoleRequest(sw, xid, role, cookie); + roleChanger.deliverRoleReply(sw, xid, role); + assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); + assertEquals(role, sw.role); + assertEquals(0, roleChanger.pendingRequestMap.get(sw).size()); + } + + @Test + public void testDeliverRoleReplyOkRepeated() { + // test normal case. Not the first role reply + int xid = (int) System.currentTimeMillis(); + long cookie = System.nanoTime(); + Role role = Role.MASTER; + OFSwitchImpl sw = new OFSwitchImpl(); + setupPendingRoleRequest(sw, xid, role, cookie); + sw.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, true); + roleChanger.deliverRoleReply(sw, xid, role); + assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); + assertEquals(role, sw.role); + assertEquals(0, roleChanger.pendingRequestMap.get(sw).size()); + } + + @Test + public void testDeliverRoleReplyNonePending() { + // nothing pending + OFSwitchImpl sw = new OFSwitchImpl(); + Channel ch = createMock(Channel.class); + SocketAddress sa = new InetSocketAddress(42); + expect(ch.getRemoteAddress()).andReturn(sa).anyTimes(); + sw.setChannel(ch); + roleChanger.deliverRoleReply(sw, 1, Role.MASTER); + assertEquals(null, sw.role); + } + + @Test + public void testDeliverRoleReplyWrongXid() { + // wrong xid received + int xid = (int) System.currentTimeMillis(); + long cookie = System.nanoTime(); + Role role = Role.MASTER; + OFSwitchImpl sw = new OFSwitchImpl(); + setupPendingRoleRequest(sw, xid, role, cookie); + Channel ch = createMock(Channel.class); + SocketAddress sa = new InetSocketAddress(42); + expect(ch.getRemoteAddress()).andReturn(sa).anyTimes(); + sw.setChannel(ch); + expect(ch.close()).andReturn(null); + replay(ch); + roleChanger.deliverRoleReply(sw, xid+1, role); + verify(ch); + assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); + assertEquals(0, roleChanger.pendingRequestMap.get(sw).size()); + } + + @Test + public void testDeliverRoleReplyWrongRole() { + // correct xid but incorrect role received + int xid = (int) System.currentTimeMillis(); + long cookie = System.nanoTime(); + Role role = Role.MASTER; + OFSwitchImpl sw = new OFSwitchImpl(); + setupPendingRoleRequest(sw, xid, role, cookie); + Channel ch = createMock(Channel.class); + SocketAddress sa = new InetSocketAddress(42); + expect(ch.getRemoteAddress()).andReturn(sa).anyTimes(); + sw.setChannel(ch); + expect(ch.close()).andReturn(null); + replay(ch); + roleChanger.deliverRoleReply(sw, xid, Role.SLAVE); + verify(ch); + assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); + assertEquals(0, roleChanger.pendingRequestMap.get(sw).size()); + } + + @Test + public void testCheckFirstPendingRoleRequestXid() { + int xid = 54321; + long cookie = 232323; + Role role = Role.MASTER; + OFSwitchImpl sw = new OFSwitchImpl(); + setupPendingRoleRequest(sw, xid, role, cookie); + assertEquals(true, + roleChanger.checkFirstPendingRoleRequestXid(sw, xid)); + assertEquals(false, + roleChanger.checkFirstPendingRoleRequestXid(sw, 0)); + roleChanger.pendingRequestMap.get(sw).clear(); + assertEquals(false, + roleChanger.checkFirstPendingRoleRequestXid(sw, xid)); + } + + @Test + public void testCheckFirstPendingRoleRequestCookie() { + int xid = 54321; + long cookie = 232323; + Role role = Role.MASTER; + OFSwitchImpl sw = new OFSwitchImpl(); + setupPendingRoleRequest(sw, xid, role, cookie); + assertEquals(true, + roleChanger.checkFirstPendingRoleRequestCookie(sw, cookie)); + assertEquals(false, + roleChanger.checkFirstPendingRoleRequestCookie(sw, 0)); + roleChanger.pendingRequestMap.get(sw).clear(); + assertEquals(false, + roleChanger.checkFirstPendingRoleRequestCookie(sw, cookie)); + } + + @Test + public void testDeliverRoleRequestNotSupported () { + // normal case. xid is pending + int xid = (int) System.currentTimeMillis(); + long cookie = System.nanoTime(); + Role role = Role.MASTER; + OFSwitchImpl sw = new OFSwitchImpl(); + setupPendingRoleRequest(sw, xid, role, cookie); + roleChanger.deliverRoleRequestNotSupported(sw, xid); + assertEquals(false, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); + assertEquals(role, sw.role); + assertEquals(0, roleChanger.pendingRequestMap.get(sw).size()); + } + + @Test + public void testDeliverRoleRequestNotSupportedNonePending() { + // nothing pending + OFSwitchImpl sw = new OFSwitchImpl(); + Channel ch = createMock(Channel.class); + SocketAddress sa = new InetSocketAddress(42); + expect(ch.getRemoteAddress()).andReturn(sa).anyTimes(); + sw.setChannel(ch); + roleChanger.deliverRoleRequestNotSupported(sw, 1); + assertEquals(null, sw.role); + } + + @Test + public void testDeliverRoleRequestNotSupportedWrongXid() { + // wrong xid received + // wrong xid received + int xid = (int) System.currentTimeMillis(); + long cookie = System.nanoTime(); + Role role = Role.MASTER; + OFSwitchImpl sw = new OFSwitchImpl(); + setupPendingRoleRequest(sw, xid, role, cookie); + Channel ch = createMock(Channel.class); + SocketAddress sa = new InetSocketAddress(42); + expect(ch.getRemoteAddress()).andReturn(sa).anyTimes(); + sw.setChannel(ch); + expect(ch.close()).andReturn(null); + replay(ch); + roleChanger.deliverRoleRequestNotSupported(sw, xid+1); + verify(ch); + assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE)); + assertEquals(0, roleChanger.pendingRequestMap.get(sw).size()); + } + } diff --git a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java index 301832f6a9400f29f28a0d7c6fa9c871e2ffc449..589a15586d78945c34d47da7a92ead1a77157595 100644 --- a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java +++ b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java @@ -355,4 +355,10 @@ public class MockFloodlightProvider implements IFloodlightModule, IFloodlightPro } + @Override + public void sendNxRoleRequest(IOFSwitch sw, int xid, Role role, long cookie) { + // TODO Auto-generated method stub + + } + } diff --git a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java index 68da09206efa9cef9ce8beecb90cbb53ad033827..04c442f25c3ff9da97002fb088bad01143130bb7 100644 --- a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java +++ b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java @@ -355,12 +355,6 @@ public class OFMessageDamperMockSwitch implements IOFSwitch { return 0; } - @Override - public boolean checkFirstPendingRoleRequestCookie(long cookie) { - // TODO Auto-generated method stub - return false; - } - @Override public void setChannel(Channel channel) { // TODO Auto-generated method stub @@ -379,18 +373,6 @@ public class OFMessageDamperMockSwitch implements IOFSwitch { } - @Override - public void deliverRoleReply(int xid, Role role) { - // TODO Auto-generated method stub - - } - - @Override - public void deliverRoleRequestNotSupported(int xid) { - // TODO Auto-generated method stub - - } - @Override public Lock getListenerReadLock() { // TODO Auto-generated method stub @@ -398,15 +380,15 @@ public class OFMessageDamperMockSwitch implements IOFSwitch { } @Override - public boolean checkFirstPendingRoleRequestXid(int xid) { + public Lock getListenerWriteLock() { // TODO Auto-generated method stub - return false; + return null; } @Override - public Lock getListenerWriteLock() { + public void setHARole(Role role, boolean haRoleReplyReceived) { // TODO Auto-generated method stub - return null; + } } \ No newline at end of file