diff --git a/protocols/ospf/ctl/src/test/java/org/onosproject/ospf/controller/impl/OspfInterfaceChannelHandlerTest.java b/protocols/ospf/ctl/src/test/java/org/onosproject/ospf/controller/impl/OspfInterfaceChannelHandlerTest.java
new file mode 100755
index 0000000..8c2e969
--- /dev/null
+++ b/protocols/ospf/ctl/src/test/java/org/onosproject/ospf/controller/impl/OspfInterfaceChannelHandlerTest.java
@@ -0,0 +1,1157 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ospf.controller.impl;
+
+import org.easymock.EasyMock;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.buffer.HeapChannelBufferFactory;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelConfig;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.ospf.controller.OspfAreaAddressRange;
+import org.onosproject.ospf.controller.OspfInterface;
+import org.onosproject.ospf.controller.OspfNbr;
+import org.onosproject.ospf.controller.OspfNeighborState;
+import org.onosproject.ospf.controller.TopologyForDeviceAndLink;
+import org.onosproject.ospf.controller.area.OspfAreaAddressRangeImpl;
+import org.onosproject.ospf.controller.area.OspfAreaImpl;
+import org.onosproject.ospf.controller.area.OspfInterfaceImpl;
+import org.onosproject.ospf.controller.util.OspfEligibleRouter;
+import org.onosproject.ospf.exceptions.OspfParseException;
+import org.onosproject.ospf.protocol.lsa.LsaHeader;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.lsa.tlvtypes.RouterTlv;
+import org.onosproject.ospf.protocol.lsa.types.RouterLsa;
+import org.onosproject.ospf.protocol.ospfpacket.OspfMessage;
+import org.onosproject.ospf.protocol.ospfpacket.subtype.LsRequestPacket;
+import org.onosproject.ospf.protocol.ospfpacket.types.DdPacket;
+import org.onosproject.ospf.protocol.ospfpacket.types.HelloPacket;
+import org.onosproject.ospf.protocol.ospfpacket.types.LsAcknowledge;
+import org.onosproject.ospf.protocol.ospfpacket.types.LsRequest;
+import org.onosproject.ospf.protocol.ospfpacket.types.LsUpdate;
+import org.onosproject.ospf.protocol.util.ChecksumCalculator;
+import org.onosproject.ospf.protocol.util.OspfInterfaceState;
+
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+
+/**
+ * Unit test class for OspfInterfaceChannelHandler.
+ */
+public class OspfInterfaceChannelHandlerTest {
+
+    private List<OspfAreaAddressRange> addressRanges;
+    private List<OspfInterface> ospfInterfaces;
+    private Controller controller;
+    private OspfAreaImpl ospfArea;
+    private OspfInterfaceImpl ospfInterface;
+    private OspfInterfaceChannelHandler ospfInterfaceChannelHandler;
+    private HashMap<String, OspfNbr> ospfNbrHashMap;
+    private OspfNbrImpl ospfNbr;
+    private Channel channel;
+    private ChannelHandlerContext channelHandlerContext;
+    private ChannelStateEvent channelStateEvent;
+    private HelloPacket helloPacket;
+    private DdPacket ddPacket;
+    private ChecksumCalculator checksumCalculator;
+    private byte[] byteArray;
+    private byte[] checkArray;
+    private ChannelBuffer buf;
+    private OspfEligibleRouter ospfEligibleRouter;
+    private LsUpdate lsUpdate;
+    private LsAcknowledge lsAck;
+    private LsRequest lsRequest;
+    private TopologyForDeviceAndLink topologyForDeviceAndLink;
+
+    @Before
+    public void setUp() throws Exception {
+        addressRanges = new ArrayList();
+        ospfInterfaces = new ArrayList<>();
+        ospfArea = createOspfArea();
+        ospfInterface = createOspfInterface();
+        ospfNbrHashMap = new HashMap();
+        topologyForDeviceAndLink = new TopologyForDeviceAndLinkImpl();
+        ospfNbr = new OspfNbrImpl(ospfArea, ospfInterface, Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  ospfInterface)
+                , topologyForDeviceAndLink);
+        ospfNbr.setNeighborId(Ip4Address.valueOf("10.10.10.10"));
+        ospfNbr.setRouterPriority(0);
+        ospfNbr.setNeighborDr(Ip4Address.valueOf("13.13.13.13"));
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        controller = new Controller();
+        ospfInterfaceChannelHandler = new OspfInterfaceChannelHandler();
+        ospfInterfaceChannelHandler = new OspfInterfaceChannelHandler(controller, ospfArea,
+                                                                      ospfInterface);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        ospfInterfaceChannelHandler = null;
+        addressRanges = null;
+        ospfInterfaces = null;
+        controller = null;
+        ospfArea = null;
+        ospfInterfaceChannelHandler = null;
+        ospfInterface = null;
+        ospfNbrHashMap = null;
+        channel = null;
+        channelHandlerContext = null;
+        channelStateEvent = null;
+        helloPacket = null;
+        ddPacket = null;
+        checksumCalculator = null;
+        byteArray = null;
+        checkArray = null;
+        ospfEligibleRouter = null;
+        lsUpdate = null;
+        lsAck = null;
+        lsRequest = null;
+    }
+
+    /**
+     * Tests interfaceUp() method.
+     */
+    @Test
+    public void testInterfaceUp() throws Exception {
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setRouterPriority(0);
+        ospfInterfaceChannelHandler.interfaceUp();
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests interfaceUp() method.
+     */
+    @Test
+    public void testInterfaceUp1() throws Exception {
+
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setRouterPriority(0);
+        ospfInterfaceChannelHandler.interfaceUp();
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests interfaceUp() method.
+     */
+    @Test
+    public void testInterfaceUp2() throws Exception {
+        ospfInterface.setInterfaceType(1);
+        ospfInterface.setRouterPriority(1);
+        ospfInterfaceChannelHandler.interfaceUp();
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests interfaceUp() method.
+     */
+    @Test
+    public void testInterfaceUp3() throws Exception {
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setRouterPriority(1);
+        ospfInterfaceChannelHandler.interfaceUp();
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests backupSeen() method.
+     */
+    @Test
+    public void testBackupSeen() throws Exception {
+        channel = EasyMock.createMock(Channel.class);
+        ospfInterface.setState(OspfInterfaceState.WAITING);
+        ospfInterfaceChannelHandler.backupSeen(channel);
+        assertThat(ospfInterface.dr(), is(notNullValue()));
+    }
+
+    /**
+     * Tests waitTimer() method.
+     */
+    @Test
+    public void testWaitTimer() throws Exception {
+        channel = EasyMock.createMock(Channel.class);
+        ospfInterface.setState(OspfInterfaceState.WAITING);
+        ospfInterface.setIpAddress(Ip4Address.valueOf("10.10.10.10"));
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterfaceChannelHandler.waitTimer(channel);
+        assertThat(ospfInterface.dr(), is(notNullValue()));
+    }
+
+    /**
+     * Tests neighborChange() method.
+     */
+    @Test
+    public void testNeighborChange() throws Exception {
+        ospfNbrHashMap = new HashMap();
+        ospfNbr = new OspfNbrImpl(new OspfAreaImpl(), new OspfInterfaceImpl(),
+                                  Ip4Address.valueOf("1.1.1.1"), Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(),
+                                                                  new OspfAreaImpl(),
+                                                                  new OspfInterfaceImpl())
+                , topologyForDeviceAndLink);
+        ospfNbr.setNeighborId(Ip4Address.valueOf("111.111.111.111"));
+        ospfNbrHashMap.put("111.111.111.111", ospfNbr);
+        ospfNbr.setState(OspfNeighborState.EXCHANGE);
+        ospfInterface.setListOfNeighbors(ospfNbrHashMap);
+        ospfInterface.setIpAddress(Ip4Address.valueOf("10.10.10.10"));
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface.setIpAddress(Ip4Address.valueOf("10.10.10.10"));
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        channel = EasyMock.createMock(Channel.class);
+        ospfInterface.setState(OspfInterfaceState.DR);
+        ospfInterfaceChannelHandler.waitTimer(channel);
+        assertThat(ospfInterface.dr(), is(Ip4Address.valueOf("0.0.0.0")));
+    }
+
+    /**
+     * Tests interfaceDown() method.
+     */
+    @Test(expected = Exception.class)
+    public void testInterfaceDown() throws Exception {
+        ospfInterfaceChannelHandler.interfaceDown();
+        assertThat(ospfInterface.state(), is(OspfInterfaceState.DOWN));
+    }
+
+    /**
+     * Tests channelConnected() method.
+     */
+    @Test(expected = Exception.class)
+    public void testChannelConnected() throws Exception {
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        channelStateEvent = EasyMock.createMock(ChannelStateEvent.class);
+        ospfInterfaceChannelHandler.channelConnected(channelHandlerContext, channelStateEvent);
+        assertThat(ospfInterface.state(), is(notNullValue()));
+    }
+
+    /**
+     * Tests exceptionCaught() method.
+     */
+    @Test(expected = Exception.class)
+    public void testExceptionCaught() throws Exception {
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        ExceptionEvent exception = EasyMock.createMock(ExceptionEvent.class);
+        ospfInterfaceChannelHandler.exceptionCaught(channelHandlerContext, exception);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests channelDisconnected() method.
+     */
+    @Test(expected = Exception.class)
+    public void testChannelDisconnected() throws Exception {
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        channelStateEvent = EasyMock.createMock(ChannelStateEvent.class);
+
+        ospfInterfaceChannelHandler.channelDisconnected(channelHandlerContext, channelStateEvent);
+
+        assertThat(ospfInterface.state(), is(notNullValue()));
+    }
+
+    /**
+     * Tests messageReceived() method.
+     */
+    @Test
+    public void testMessageReceived() throws Exception {
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setInterfaceType(2);
+        ospfArea.setAreaId(Ip4Address.valueOf("13.13.13.13"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        MessageEvent messageEvent = new MessageEvent() {
+            @Override
+            public Object getMessage() {
+                helloPacket = new HelloPacket();
+                helloPacket.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+                helloPacket.setRouterId(Ip4Address.valueOf("10.10.10.10"));
+                helloPacket.setOspfVer(2);
+                helloPacket.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+                helloPacket.setOptions(2);
+                helloPacket.setAreaId(Ip4Address.valueOf("5.5.5.5"));
+                helloPacket.setNetworkMask(Ip4Address.valueOf("3.3.3.3"));
+                helloPacket.setOspftype(1);
+                helloPacket.setAuthType(0);
+                helloPacket.setAuthentication(0);
+                checksumCalculator = new ChecksumCalculator();
+                byteArray = helloPacket.asBytes();
+                helloPacket.setOspfPacLength(byteArray.length);
+                checkArray = checksumCalculator.calculateOspfCheckSum(byteArray, 12, 13);
+                buf = ChannelBuffers.copiedBuffer(checkArray);
+                helloPacket.setChecksum(buf.readUnsignedShort());
+                List<HelloPacket> messPackets = new ArrayList<>();
+                messPackets.add(helloPacket);
+                return messPackets;
+            }
+
+            @Override
+            public SocketAddress getRemoteAddress() {
+                return null;
+            }
+
+            @Override
+            public Channel getChannel() {
+                return null;
+            }
+
+            @Override
+            public ChannelFuture getFuture() {
+                return null;
+            }
+        };
+        ospfInterfaceChannelHandler.messageReceived(channelHandlerContext, messageEvent);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests processOSPFMessage() method.
+     */
+    @Test
+    public void testProcessOSPFMessage() throws Exception {
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("225.225.225.225"));
+        ospfInterface.setInterfaceType(2);
+        ospfArea.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        OspfMessage message;
+        helloPacket = new HelloPacket();
+        helloPacket.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        helloPacket.setRouterId(Ip4Address.valueOf("10.10.10.10"));
+        helloPacket.setOspfVer(2);
+        helloPacket.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        helloPacket.setOptions(2);
+        helloPacket.setNetworkMask(Ip4Address.valueOf("3.3.3.3"));
+        helloPacket.setOspftype(1);
+        helloPacket.setAuthType(0);
+        helloPacket.setHelloInterval(60);
+        helloPacket.setRouterDeadInterval(60);
+        helloPacket.setAuthentication(0);
+        checksumCalculator = new ChecksumCalculator();
+        byteArray = helloPacket.asBytes();
+        helloPacket.setOspfPacLength(byteArray.length);
+        checkArray = checksumCalculator.calculateOspfCheckSum(byteArray, 12, 13);
+        checkArray[0] = -53;
+        checkArray[1] = 37;
+        buf = ChannelBuffers.copiedBuffer(checkArray);
+        helloPacket.setChecksum(buf.readUnsignedShort());
+        message = helloPacket;
+        ospfInterfaceChannelHandler.processOSPFMessage(message, channelHandlerContext);
+        ddPacket = new DdPacket();
+        ddPacket.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        ddPacket.setRouterId(Ip4Address.valueOf("10.10.10.10"));
+        ddPacket.setOspfVer(2);
+        ddPacket.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        ddPacket.setOptions(2);
+        ddPacket.setOspftype(2);
+        ddPacket.setAuthType(0);
+        ddPacket.setAuthentication(0);
+        checksumCalculator = new ChecksumCalculator();
+        byteArray = ddPacket.asBytes();
+        ddPacket.setOspfPacLength(byteArray.length);
+        checkArray = checksumCalculator.calculateOspfCheckSum(byteArray, 12, 13);
+        checkArray[0] = -49;
+        checkArray[1] = -79;
+        buf = ChannelBuffers.copiedBuffer(checkArray);
+        ddPacket.setChecksum(buf.readUnsignedShort());
+        message = ddPacket;
+        ospfInterfaceChannelHandler.processOSPFMessage(message, channelHandlerContext);
+        lsRequest = new LsRequest();
+        lsRequest.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        lsRequest.setRouterId(Ip4Address.valueOf("10.10.10.10"));
+        lsRequest.setOspfVer(2);
+        lsRequest.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        lsRequest.setOspftype(3);
+        lsRequest.setAuthType(0);
+        lsRequest.setAuthentication(0);
+        checksumCalculator = new ChecksumCalculator();
+        byteArray = lsRequest.asBytes();
+        lsRequest.setOspfPacLength(byteArray.length);
+        checkArray = checksumCalculator.calculateOspfCheckSum(byteArray, 12, 13);
+        checkArray[0] = -33;
+        checkArray[1] = -58;
+        buf = ChannelBuffers.copiedBuffer(checkArray);
+        lsRequest.setChecksum(buf.readUnsignedShort());
+        message = lsRequest;
+        ospfInterfaceChannelHandler.processOSPFMessage(message, channelHandlerContext);
+        lsUpdate = new LsUpdate();
+        lsUpdate.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        lsUpdate.setRouterId(Ip4Address.valueOf("10.10.10.10"));
+        lsUpdate.setOspfVer(2);
+        lsUpdate.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        lsUpdate.setOspftype(4);
+        lsUpdate.setAuthType(0);
+        lsUpdate.setAuthentication(0);
+        checksumCalculator = new ChecksumCalculator();
+        byteArray = lsUpdate.asBytes();
+        lsUpdate.setOspfPacLength(byteArray.length);
+        checkArray = checksumCalculator.calculateOspfCheckSum(byteArray, 12, 13);
+        checkArray[0] = -47;
+        checkArray[1] = -77;
+        buf = ChannelBuffers.copiedBuffer(checkArray);
+        lsUpdate.setChecksum(buf.readUnsignedShort());
+        message = lsUpdate;
+        ospfInterfaceChannelHandler.processOSPFMessage(message, channelHandlerContext);
+        lsAck = new LsAcknowledge();
+        lsAck.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        lsAck.setRouterId(Ip4Address.valueOf("10.10.10.10"));
+        lsAck.setOspfVer(2);
+        lsAck.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        lsAck.setOspftype(5);
+        lsAck.setAuthType(0);
+        lsAck.setAuthentication(0);
+        checksumCalculator = new ChecksumCalculator();
+        byteArray = lsAck.asBytes();
+        lsAck.setOspfPacLength(byteArray.length);
+        checkArray = checksumCalculator.calculateOspfCheckSum(byteArray, 12, 13);
+        checkArray[0] = -47;
+        checkArray[1] = -74;
+        buf = ChannelBuffers.copiedBuffer(checkArray);
+        lsAck.setChecksum(buf.readUnsignedShort());
+        message = lsAck;
+        ospfInterfaceChannelHandler.processOSPFMessage(message, channelHandlerContext);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+
+    }
+
+    /**
+     * Tests processHelloMessage() method.
+     */
+    @Test
+    public void testProcessHelloMessage() throws Exception {
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setInterfaceType(1);
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("244.244.244.244"));
+        ospfInterface.setHelloIntervalTime(10);
+        ospfInterface.setRouterDeadIntervalTime(10);
+        ospfArea.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        OspfMessage message;
+        helloPacket = new HelloPacket();
+        helloPacket.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        helloPacket.setOspfVer(2);
+        helloPacket.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        helloPacket.setNetworkMask(Ip4Address.valueOf("244.244.244.244"));
+        helloPacket.setHelloInterval(10);
+        helloPacket.setRouterDeadInterval(10);
+        helloPacket.setDr(Ip4Address.valueOf("10.10.10.10"));
+        helloPacket.setBdr(Ip4Address.valueOf("11.11.11.11"));
+        helloPacket.setRouterId(Ip4Address.valueOf("111.111.111.111"));
+        message = helloPacket;
+        ospfInterfaceChannelHandler.processHelloMessage(message, channelHandlerContext);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests processHelloMessage() method.
+     */
+    @Test
+    public void testProcessHelloMessage1() throws Exception {
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setRouterPriority(1);
+        ospfInterfaceChannelHandler.interfaceUp();
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setState(OspfInterfaceState.WAITING);
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("244.244.244.244"));
+        ospfInterface.setHelloIntervalTime(10);
+        ospfInterface.setRouterDeadIntervalTime(10);
+        ospfArea.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        OspfMessage message;
+        helloPacket = new HelloPacket();
+        helloPacket.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        helloPacket.setOspfVer(2);
+        helloPacket.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        helloPacket.setNetworkMask(Ip4Address.valueOf("244.244.244.244"));
+        helloPacket.setHelloInterval(10);
+        helloPacket.setRouterDeadInterval(10);
+        helloPacket.setDr(Ip4Address.valueOf("10.10.10.10"));
+        helloPacket.setBdr(Ip4Address.valueOf("11.11.11.11"));
+        helloPacket.setRouterId(Ip4Address.valueOf("2.2.2.2"));
+        message = helloPacket;
+        ospfInterfaceChannelHandler.processHelloMessage(message, channelHandlerContext);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+        ospfNbrHashMap = new HashMap();
+        ospfNbr = new OspfNbrImpl(ospfArea, ospfInterface, Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  ospfInterface)
+                , topologyForDeviceAndLink);
+        ospfNbr.setNeighborId(Ip4Address.valueOf("2.2.2.2"));
+        ospfNbr.setRouterPriority(0);
+        ospfNbr.setNeighborDr(Ip4Address.valueOf("13.13.13.13"));
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        ospfInterfaceChannelHandler.processHelloMessage(message, channelHandlerContext);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests processDdMessage() method.
+     */
+    @Test
+    public void testProcessDdMessage() throws Exception {
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface.setHelloIntervalTime(10);
+        ospfInterface.setRouterDeadIntervalTime(10);
+        ospfArea.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        OspfMessage message;
+        ddPacket = new DdPacket();
+        ddPacket.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        ddPacket.setOspfVer(2);
+        ddPacket.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        ddPacket.setRouterId(Ip4Address.valueOf("2.2.2.2"));
+        ddPacket.setIsOpaqueCapable(true);
+        ddPacket.setIsMore(1);
+        ddPacket.setIsInitialize(1);
+        ddPacket.setIsMaster(1);
+        ddPacket.setSequenceNo(123);
+        message = ddPacket;
+        ospfNbrHashMap = new HashMap();
+        ospfNbr = new OspfNbrImpl(ospfArea, ospfInterface, Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  ospfInterface)
+                , topologyForDeviceAndLink);
+        ospfNbr.setLastDdPacket(createDdPacket());
+        ospfNbr.setNeighborId(Ip4Address.valueOf("2.2.2.2"));
+        ospfNbr.setState(OspfNeighborState.EXSTART);
+        ospfNbr.setRouterPriority(0);
+        ospfNbr.setNeighborDr(Ip4Address.valueOf("13.13.13.13"));
+        ospfNbr.setDdSeqNum(123);
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        ospfInterfaceChannelHandler.processDdMessage(message, channelHandlerContext);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests processDdMessage() method.
+     */
+    @Test(expected = Exception.class)
+    public void testProcessDdMessage3() throws Exception {
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface.setHelloIntervalTime(10);
+        ospfInterface.setRouterDeadIntervalTime(10);
+        ospfArea.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        OspfMessage message;
+        ddPacket = new DdPacket();
+        ddPacket.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        ddPacket.setOspfVer(2);
+        ddPacket.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        ddPacket.setRouterId(Ip4Address.valueOf("2.2.2.2"));
+        ddPacket.setIsOpaqueCapable(true);
+        ddPacket.setIsMore(1);
+        ddPacket.setIsInitialize(1);
+        ddPacket.setIsMaster(1);
+        ddPacket.setSequenceNo(123);
+        message = ddPacket;
+        ospfNbrHashMap = new HashMap();
+        ospfNbr = new OspfNbrImpl(ospfArea, ospfInterface, Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  ospfInterface)
+                , topologyForDeviceAndLink);
+        ospfNbr.setLastDdPacket(createDdPacket());
+        ospfNbr.setNeighborId(Ip4Address.valueOf("2.2.2.2"));
+        ospfNbr.setState(OspfNeighborState.EXSTART);
+        ospfNbr.setRouterPriority(0);
+        ospfNbr.setNeighborDr(Ip4Address.valueOf("13.13.13.13"));
+        ospfNbr.setDdSeqNum(123);
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        ddPacket.setIsMore(1);
+        ddPacket.setIsInitialize(0);
+        ddPacket.setIsMaster(0);
+        ddPacket.setSequenceNo(123);
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        ospfInterfaceChannelHandler.processDdMessage(message, channelHandlerContext);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests processDdMessage() method.
+     */
+    @Test(expected = Exception.class)
+    public void testProcessDdMessage1() throws Exception {
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface.setHelloIntervalTime(10);
+        ospfInterface.setRouterDeadIntervalTime(10);
+        ospfArea.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        OspfMessage message;
+        ddPacket = new DdPacket();
+        ddPacket.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        ddPacket.setOspfVer(2);
+        ddPacket.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        ddPacket.setRouterId(Ip4Address.valueOf("2.2.2.2"));
+        ddPacket.setIsOpaqueCapable(true);
+        ddPacket.setIsMore(1);
+        ddPacket.setIsInitialize(1);
+        ddPacket.setIsMaster(1);
+        ddPacket.setSequenceNo(123);
+        message = ddPacket;
+        ospfNbrHashMap = new HashMap();
+        ospfNbr = new OspfNbrImpl(ospfArea, ospfInterface, Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  ospfInterface)
+                , topologyForDeviceAndLink);
+        ospfNbr.setLastDdPacket(createDdPacket());
+        ospfNbr.setNeighborId(Ip4Address.valueOf("2.2.2.2"));
+        ospfNbr.setState(OspfNeighborState.EXCHANGE);
+        ospfNbr.setRouterPriority(0);
+        ospfNbr.setNeighborDr(Ip4Address.valueOf("13.13.13.13"));
+        ospfNbr.setDdSeqNum(123);
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        ddPacket.setIsMore(1);
+        ddPacket.setIsInitialize(0);
+        ddPacket.setIsMaster(0);
+        ddPacket.setSequenceNo(123);
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        ospfInterfaceChannelHandler.processDdMessage(message, channelHandlerContext);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+
+    }
+
+    /**
+     * Tests processDdMessage() method.
+     */
+    @Test(expected = Exception.class)
+    public void testProcessDdMessage2() throws Exception {
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface.setHelloIntervalTime(10);
+        ospfInterface.setRouterDeadIntervalTime(10);
+        ospfArea.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        OspfMessage message;
+        ddPacket = new DdPacket();
+        ddPacket.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        ddPacket.setOspfVer(2);
+        ddPacket.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        ddPacket.setRouterId(Ip4Address.valueOf("2.2.2.2"));
+        ddPacket.setIsOpaqueCapable(true);
+        ddPacket.setIsMore(1);
+        ddPacket.setIsInitialize(1);
+        ddPacket.setIsMaster(1);
+        ddPacket.setSequenceNo(123);
+        message = ddPacket;
+        ospfNbrHashMap = new HashMap();
+        ospfNbr = new OspfNbrImpl(ospfArea, ospfInterface, Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  ospfInterface)
+                , topologyForDeviceAndLink);
+        ospfNbr.setLastDdPacket(createDdPacket());
+        ospfNbr.setNeighborId(Ip4Address.valueOf("2.2.2.2"));
+        ospfNbr.setState(OspfNeighborState.LOADING);
+        ospfNbr.setRouterPriority(0);
+        ospfNbr.setNeighborDr(Ip4Address.valueOf("13.13.13.13"));
+        ospfNbr.setDdSeqNum(123);
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        ospfInterfaceChannelHandler.processDdMessage(message, channelHandlerContext);
+        ddPacket.setIsMore(1);
+        ddPacket.setIsInitialize(0);
+        ddPacket.setIsMaster(0);
+        ddPacket.setSequenceNo(123);
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        ospfNbr.setState(OspfNeighborState.LOADING);
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+
+        ospfInterfaceChannelHandler.processDdMessage(message, channelHandlerContext);
+
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+
+    }
+
+    /**
+     * Tests processLsRequestMessage() method.
+     */
+    @Test
+    public void testProcessLSRequestMessage() throws Exception {
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface.setHelloIntervalTime(10);
+        ospfInterface.setRouterDeadIntervalTime(10);
+        ospfArea.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        OspfMessage message;
+        lsRequest = new LsRequest();
+        lsRequest.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        lsRequest.setOspfVer(2);
+        lsRequest.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        lsRequest.setRouterId(Ip4Address.valueOf("10.226.165.100"));
+        List<LsRequestPacket> lsRequests = new ArrayList();
+        LsRequestPacket lsRequestPacket = new LsRequestPacket();
+        lsRequestPacket.setLsType(3);
+        lsRequestPacket.setLinkStateId("2.2.2.2");
+        lsRequestPacket.setOwnRouterId("2.2.2.2");
+        lsRequests.add(lsRequestPacket);
+        lsRequests.add(lsRequestPacket);
+        lsRequest.addLinkStateRequests(new LsRequestPacket());
+        lsRequest.addLinkStateRequests(new LsRequestPacket());
+        message = lsRequest;
+        ospfNbrHashMap = new HashMap();
+        ospfNbr.setState(OspfNeighborState.EXCHANGE);
+        ospfNbr = new OspfNbrImpl(ospfArea, createOspfInterface(), Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("10.226.165.100"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  createOspfInterface1())
+                , topologyForDeviceAndLink);
+        ospfNbr.setLastDdPacket(createDdPacket());
+        ospfNbr.setNeighborId(Ip4Address.valueOf("2.2.2.2"));
+        ospfNbr.setState(OspfNeighborState.FULL);
+        ospfNbr.setRouterPriority(0);
+        ospfNbr.setNeighborDr(Ip4Address.valueOf("13.13.13.13"));
+        ospfNbr.setDdSeqNum(123);
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        ospfInterface.setListOfNeighbors(ospfNbrHashMap);
+        ospfInterfaceChannelHandler.processLsRequestMessage(message, channelHandlerContext);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+
+    }
+
+    /**
+     * Tests processLsUpdateMessage() method.
+     */
+    @Test
+    public void testProcessLSUpdateMessage() throws Exception {
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface.setHelloIntervalTime(10);
+        ospfInterface.setRouterDeadIntervalTime(10);
+        ospfArea.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        OspfMessage message;
+        lsUpdate = new LsUpdate();
+        lsUpdate.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        lsUpdate.setOspfVer(2);
+        lsUpdate.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        lsUpdate.setRouterId(Ip4Address.valueOf("10.226.165.100"));
+        RouterLsa routerLsa = new RouterLsa();
+        lsUpdate.addLsa(routerLsa);
+        lsUpdate.setNumberOfLsa(1);
+        message = lsUpdate;
+        ospfNbrHashMap = new HashMap();
+        ospfNbr.setState(OspfNeighborState.FULL);
+        ospfNbr = new OspfNbrImpl(ospfArea, createOspfInterface(), Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("10.226.165.100"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  createOspfInterface1())
+                , topologyForDeviceAndLink);
+        ospfNbr.setLastDdPacket(createDdPacket());
+        ospfNbr.setNeighborId(Ip4Address.valueOf("2.2.2.2"));
+        ospfNbr.setState(OspfNeighborState.FULL);
+        ospfNbr.setRouterPriority(0);
+        ospfNbr.setNeighborDr(Ip4Address.valueOf("13.13.13.13"));
+        ospfNbr.setDdSeqNum(123);
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        ospfInterfaceChannelHandler.processLsUpdateMessage(message, channelHandlerContext);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+
+    }
+
+    @Test(expected = Exception.class)
+    public void testProcessLSAckMessage() throws Exception {
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface.setHelloIntervalTime(10);
+        ospfInterface.setRouterDeadIntervalTime(10);
+        ospfArea.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        OspfMessage message;
+        lsAck = new LsAcknowledge();
+        lsAck.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        lsAck.setOspfVer(2);
+        lsAck.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        LsaHeader lsaHeader = new LsaHeader();
+        lsAck.addLinkStateHeader(lsaHeader);
+        message = lsAck;
+        ospfNbr = new OspfNbrImpl(ospfArea, createOspfInterface(), Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("10.226.165.100"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  createOspfInterface())
+                , topologyForDeviceAndLink);
+        ospfNbr.setLastDdPacket(createDdPacket());
+        ospfNbr.setNeighborId(Ip4Address.valueOf("2.2.2.2"));
+        ospfNbr.setState(OspfNeighborState.FULL);
+        ospfNbr.setRouterPriority(0);
+        ospfNbr.setNeighborDr(Ip4Address.valueOf("13.13.13.13"));
+        ospfNbr.setDdSeqNum(123);
+        ospfInterfaceChannelHandler.processLsAckMessage(message, channelHandlerContext);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+
+    }
+
+    /**
+     * Tests compareDdPackets() method.
+     */
+    @Test
+    public void testCompareDDPackets() throws Exception {
+        ospfInterface.setIpAddress(Ip4Address.valueOf("11.11.11.11"));
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface.setHelloIntervalTime(10);
+        ospfInterface.setRouterDeadIntervalTime(10);
+        ospfArea.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+        OspfMessage message;
+        ddPacket = new DdPacket();
+        ddPacket.setSourceIp(Ip4Address.valueOf("1.1.1.1"));
+        ddPacket.setOspfVer(2);
+        ddPacket.setIsInitialize(1);
+        ddPacket.setIsMaster(1);
+        ddPacket.setIsMore(1);
+        ddPacket.setOptions(2);
+        ddPacket.setAreaId(Ip4Address.valueOf("12.12.12.12"));
+        assertThat(ospfInterfaceChannelHandler.compareDdPackets(ddPacket, ddPacket), is(true));
+    }
+
+    @Test(expected = Exception.class)
+    public void testCloseChannel() throws Exception {
+        channelHandlerContext = EasyMock.createMock(ChannelHandlerContext.class);
+
+        ospfInterfaceChannelHandler.closeChannel(channelHandlerContext);
+
+        assertThat(ospfInterface.dr(), is(notNullValue()));
+    }
+
+    /**
+     * Tests electRouter() method.
+     */
+    @Test
+    public void testElectRouter() throws Exception {
+        ospfInterface.setDr(Ip4Address.valueOf("3.3.3.3"));
+        ospfInterface.setBdr(Ip4Address.valueOf("3.3.3.3"));
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ChannelConfig channelConfig = EasyMock.createMock(ChannelConfig.class);
+        EasyMock.expect(channelConfig.getBufferFactory()).andReturn(new HeapChannelBufferFactory());
+        Channel channel = EasyMock.createMock(Channel.class);
+        ospfInterfaceChannelHandler.electRouter(channel);
+        assertThat(ospfInterface.dr(), is(notNullValue()));
+    }
+
+    /**
+     * Tests electBdr() method.
+     */
+    @Test
+    public void testElectBdr() throws Exception {
+        ospfEligibleRouter = new OspfEligibleRouter();
+        ospfEligibleRouter.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsDr(true);
+        ospfEligibleRouter.setRouterPriority(10);
+        ospfEligibleRouter.setRouterId(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsBdr(false);
+        OspfEligibleRouter ospfEligibleRouter1 = new OspfEligibleRouter();
+        ospfEligibleRouter.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsDr(true);
+        ospfEligibleRouter.setRouterPriority(10);
+        ospfEligibleRouter.setRouterId(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsBdr(false);
+        OspfEligibleRouter ospfEligibleRouter2 = new OspfEligibleRouter();
+        ospfEligibleRouter.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsDr(true);
+        ospfEligibleRouter.setRouterPriority(10);
+        ospfEligibleRouter.setRouterId(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsBdr(false);
+        List<OspfEligibleRouter> ospfEligibleRouters = new ArrayList<>();
+
+        ospfEligibleRouters.add(ospfEligibleRouter);
+        ospfEligibleRouters.add(ospfEligibleRouter1);
+        ospfEligibleRouters.add(ospfEligibleRouter2);
+        OspfEligibleRouter eligibleRouter = ospfInterfaceChannelHandler.electBdr(ospfEligibleRouters);
+        assertThat(ospfEligibleRouters.size(), is(3));
+        assertThat(eligibleRouter, is(notNullValue()));
+    }
+
+    /**
+     * Tests electDr() method.
+     */
+    @Test
+    public void testElectDR() throws Exception {
+        ospfEligibleRouter = new OspfEligibleRouter();
+        ospfEligibleRouter.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsDr(true);
+        ospfEligibleRouter.setRouterPriority(10);
+        ospfEligibleRouter.setRouterId(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsBdr(false);
+        OspfEligibleRouter ospfEligibleRouter1 = new OspfEligibleRouter();
+        ospfEligibleRouter.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsDr(true);
+        ospfEligibleRouter.setRouterPriority(10);
+        ospfEligibleRouter.setRouterId(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsBdr(false);
+        OspfEligibleRouter ospfEligibleRouter2 = new OspfEligibleRouter();
+        ospfEligibleRouter.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsDr(true);
+        ospfEligibleRouter.setRouterPriority(10);
+        ospfEligibleRouter.setRouterId(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsBdr(false);
+        List<OspfEligibleRouter> ospfEligibleRouters = new ArrayList<>();
+        ospfEligibleRouters.add(ospfEligibleRouter);
+        ospfEligibleRouters.add(ospfEligibleRouter1);
+        ospfEligibleRouters.add(ospfEligibleRouter2);
+        OspfEligibleRouter eligibleRouter = ospfInterfaceChannelHandler.electDr(ospfEligibleRouters,
+                                                                                ospfEligibleRouter);
+        assertThat(ospfEligibleRouters.size(), is(3));
+        assertThat(eligibleRouter, is(notNullValue()));
+    }
+
+    /**
+     * Tests selectRouterBasedOnPriority() method.
+     */
+    @Test
+    public void testSelectRouterBasedOnPriority() throws Exception {
+        ospfEligibleRouter = new OspfEligibleRouter();
+        ospfEligibleRouter.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsDr(true);
+        ospfEligibleRouter.setRouterPriority(10);
+        ospfEligibleRouter.setRouterId(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsBdr(false);
+        OspfEligibleRouter ospfEligibleRouter1 = new OspfEligibleRouter();
+        ospfEligibleRouter.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsDr(true);
+        ospfEligibleRouter.setRouterPriority(11);
+        ospfEligibleRouter.setRouterId(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsBdr(false);
+        OspfEligibleRouter ospfEligibleRouter2 = new OspfEligibleRouter();
+        ospfEligibleRouter.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsDr(true);
+        ospfEligibleRouter.setRouterPriority(12);
+        ospfEligibleRouter.setRouterId(Ip4Address.valueOf("1.1.1.1"));
+        ospfEligibleRouter.setIsBdr(false);
+        List<OspfEligibleRouter> ospfEligibleRouters = new ArrayList<>();
+        ospfEligibleRouters.add(ospfEligibleRouter);
+        ospfEligibleRouters.add(ospfEligibleRouter1);
+        ospfEligibleRouters.add(ospfEligibleRouter2);
+        OspfEligibleRouter eligibleRouter = ospfInterfaceChannelHandler.selectRouterBasedOnPriority(
+                ospfEligibleRouters);
+        assertThat(eligibleRouter, is(notNullValue()));
+    }
+
+    /**
+     * Tests addDeviceInformation() method.
+     */
+    @Test(expected = Exception.class)
+    public void testAddDeviceInformation() throws Exception {
+        ospfNbr = new OspfNbrImpl(ospfArea, createOspfInterface(), Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("10.226.165.100"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  createOspfInterface())
+                , topologyForDeviceAndLink);
+
+        ospfInterfaceChannelHandler.addDeviceInformation(new OspfRouterImpl());
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests removeDeviceInformation() method.
+     */
+    @Test(expected = Exception.class)
+    public void testRemoveDeviceInformation() throws Exception {
+        ospfNbr = new OspfNbrImpl(ospfArea, createOspfInterface(), Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("10.226.165.100"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  createOspfInterface())
+                , topologyForDeviceAndLink);
+
+        ospfInterfaceChannelHandler.removeDeviceInformation(new OspfRouterImpl());
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests addLinkInformation() method.
+     */
+    @Test(expected = Exception.class)
+    public void testaddLinkInformation() throws Exception {
+        ospfNbr = new OspfNbrImpl(ospfArea, createOspfInterface(), Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("10.226.165.100"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  createOspfInterface())
+                , topologyForDeviceAndLink);
+
+        List topTlv = new ArrayList();
+        topTlv.add(new RouterTlv(new TlvHeader()));
+        ospfInterfaceChannelHandler.addLinkInformation(new OspfRouterImpl(), new OspfLinkTedImpl());
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Tests removeLinkInformation() method.
+     */
+    @Test(expected = Exception.class)
+    public void testRemoveLinkInformation() throws Exception {
+        ospfNbr = new OspfNbrImpl(ospfArea, createOspfInterface(), Ip4Address.valueOf("10.10.10.10"),
+                                  Ip4Address.valueOf("10.226.165.100"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(), ospfArea,
+                                                                  createOspfInterface())
+                , topologyForDeviceAndLink);
+
+        ospfInterfaceChannelHandler.removeLinkInformation(ospfNbr);
+        assertThat(ospfInterfaceChannelHandler, is(notNullValue()));
+    }
+
+    /**
+     * Utility for test method.
+     */
+    private DdPacket createDdPacket() throws OspfParseException {
+        byte[] ddPacket = {2, 2, 0, 32, -64, -88, -86, 8, 0, 0, 0, 1, -96, 82,
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, -36, 2, 7, 65, 119, -87, 126};
+        DdPacket ddPacket1 = new DdPacket();
+        ChannelBuffer buf = ChannelBuffers.buffer(ddPacket.length);
+        buf.writeBytes(ddPacket);
+        ddPacket1.readFrom(buf);
+        return ddPacket1;
+    }
+
+    /**
+     * Utility for test method.
+     */
+    private OspfInterfaceImpl createOspfInterface() throws UnknownHostException {
+        ospfInterface = new OspfInterfaceImpl();
+        OspfAreaImpl ospfArea = new OspfAreaImpl();
+        OspfInterfaceChannelHandler ospfInterfaceChannelHandler = EasyMock.createMock(
+                OspfInterfaceChannelHandler.class);
+        ospfNbr = new OspfNbrImpl(ospfArea, ospfInterface, Ip4Address.valueOf("10.226.165.164"),
+                                  Ip4Address.valueOf("1.1.1.1"), 2, ospfInterfaceChannelHandler
+                , topologyForDeviceAndLink);
+        ospfNbr.setState(OspfNeighborState.EXSTART);
+        ospfNbr.setNeighborId(Ip4Address.valueOf("10.226.165.100"));
+        this.ospfInterface = new OspfInterfaceImpl();
+        this.ospfInterface.setIpAddress(Ip4Address.valueOf("10.226.165.164"));
+        this.ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        this.ospfInterface.setAreaId(2);
+        this.ospfInterface.setAuthKey("authKey");
+        this.ospfInterface.setAuthType("AuthReq");
+        this.ospfInterface.setBdr(Ip4Address.valueOf("111.111.111.111"));
+        this.ospfInterface.setDr(Ip4Address.valueOf("111.111.111.111"));
+        this.ospfInterface.setHelloIntervalTime(20);
+        this.ospfInterface.setInterfaceCost(10);
+        this.ospfInterface.setInterfaceType(2);
+        this.ospfInterface.setReTransmitInterval(2000);
+        this.ospfInterface.setMtu(6500);
+        this.ospfInterface.setPollInterval(1000);
+        this.ospfInterface.setRouterDeadIntervalTime(1000);
+        this.ospfInterface.setRouterPriority(1);
+        this.ospfInterface.setTransmitDelay(500);
+        this.ospfInterface.setInterfaceType(1);
+        this.ospfInterface.addNeighbouringRouter(ospfNbr);
+        return this.ospfInterface;
+    }
+
+    /**
+     * Utility for test method.
+     */
+    private OspfInterfaceImpl createOspfInterface1() throws UnknownHostException {
+        ospfInterface = new OspfInterfaceImpl();
+        OspfAreaImpl ospfArea = new OspfAreaImpl();
+        OspfInterfaceChannelHandler ospfInterfaceChannelHandler = EasyMock.createMock(
+                OspfInterfaceChannelHandler.class);
+        ospfNbr = new OspfNbrImpl(ospfArea, ospfInterface, Ip4Address.valueOf("10.226.165.164"),
+                                  Ip4Address.valueOf("1.1.1.1"), 2, ospfInterfaceChannelHandler
+                , topologyForDeviceAndLink);
+        ospfNbr.setState(OspfNeighborState.FULL);
+        ospfNbr.setNeighborId(Ip4Address.valueOf("10.226.165.100"));
+        ospfInterface = new OspfInterfaceImpl();
+        ospfInterface.setIpAddress(Ip4Address.valueOf("10.226.165.164"));
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface.setAreaId(2);
+        ospfInterface.setAuthKey("authKey");
+        ospfInterface.setAuthType("AuthReq");
+        ospfInterface.setBdr(Ip4Address.valueOf("111.111.111.111"));
+        ospfInterface.setDr(Ip4Address.valueOf("111.111.111.111"));
+        ospfInterface.setHelloIntervalTime(20);
+        ospfInterface.setInterfaceCost(10);
+        ospfInterface.setInterfaceType(2);
+        ospfInterface.setReTransmitInterval(2000);
+        ospfInterface.setMtu(6500);
+        ospfInterface.setPollInterval(1000);
+        ospfInterface.setRouterDeadIntervalTime(1000);
+        ospfInterface.setRouterPriority(1);
+        ospfInterface.setTransmitDelay(500);
+        ospfInterface.setInterfaceType(1);
+        ospfInterface.addNeighbouringRouter(ospfNbr);
+        return ospfInterface;
+    }
+
+    /**
+     * Utility for test method.
+     */
+    private OspfAreaImpl createOspfArea() throws UnknownHostException {
+        OspfAreaAddressRangeImpl ospfAreaAddressRange;
+        ospfAreaAddressRange = createOspfAreaAddressRange();
+        addressRanges.add(ospfAreaAddressRange);
+        OspfAreaImpl ospfArea = new OspfAreaImpl();
+        ospfArea.setStubCost(10);
+        ospfArea.setAreaId(Ip4Address.valueOf("10.226.165.164"));
+        ospfArea.setExternalRoutingCapability(true);
+        ospfArea.setTransitCapability(true);
+        ospfArea.setAddressRanges(addressRanges);
+        OspfInterfaceImpl ospfInterface = createOspfInterface();
+        ospfInterfaces.add(ospfInterface);
+        ospfArea.setInterfacesLst(ospfInterfaces);
+        RouterLsa routerLsa = new RouterLsa();
+        routerLsa.setLsType(1);
+        routerLsa.setLinkStateId("2.2.2.2");
+        routerLsa.setAdvertisingRouter(Ip4Address.valueOf("2.2.2.2"));
+        try {
+            ospfArea.addLsa(routerLsa, false, ospfInterface);
+        } catch (Exception e) {
+            System.out.println("ospfAreaImpl createOspfArea");
+        }
+        ospfArea.setRouterId(Ip4Address.valueOf("111.111.111.111"));
+
+        return ospfArea;
+    }
+
+    /**
+     * Utility for test method.
+     */
+    private OspfAreaAddressRangeImpl createOspfAreaAddressRange() {
+        OspfAreaAddressRangeImpl ospfAreaAddressRange = new OspfAreaAddressRangeImpl();
+        ospfAreaAddressRange.setIpAddress(Ip4Address.valueOf("10.226.165.164"));
+        ospfAreaAddressRange.setAdvertise(true);
+        ospfAreaAddressRange.setMask("mask");
+        return ospfAreaAddressRange;
+    }
+
+}
\ No newline at end of file
