diff --git a/src/main/java/net/onrc/onos/core/devicemanager/OnosDeviceManager.java b/src/main/java/net/onrc/onos/core/devicemanager/OnosDeviceManager.java
index 38a8746..f1cc8f7 100644
--- a/src/main/java/net/onrc/onos/core/devicemanager/OnosDeviceManager.java
+++ b/src/main/java/net/onrc/onos/core/devicemanager/OnosDeviceManager.java
@@ -58,7 +58,7 @@
     private IDatagridService datagrid;
     private IEventChannel<Long, OnosDevice> eventChannel;
     private static final String DEVICE_CHANNEL_NAME = "onos.device";
-    private Map<Long, OnosDevice> mapDevice = new ConcurrentHashMap<Long, OnosDevice>();
+    private final Map<Long, OnosDevice> mapDevice = new ConcurrentHashMap<Long, OnosDevice>();
     private ITopologyService topologyService;
     private Topology topology;
 
@@ -67,8 +67,8 @@
     }
 
     private class OnosDeviceUpdate implements IUpdate {
-        private OnosDevice device;
-        private OnosDeviceUpdateType type;
+        private final OnosDevice device;
+        private final OnosDeviceUpdateType type;
 
         public OnosDeviceUpdate(OnosDevice device, OnosDeviceUpdateType type) {
             this.device = device;
@@ -110,7 +110,7 @@
     @Override
     public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
         if (msg.getType().equals(OFType.PACKET_IN) &&
-            (msg instanceof OFPacketIn)) {
+                (msg instanceof OFPacketIn)) {
             OFPacketIn pi = (OFPacketIn) msg;
 
             Ethernet eth = IFloodlightProviderService.bcStore.
@@ -250,14 +250,16 @@
      * @param pi  the original packetin
      * @return the entity from the packet
      */
-    private OnosDevice getSourceDeviceFromPacket(Ethernet eth,
-                                                 long swdpid,
-                                                 short port) {
+    protected OnosDevice getSourceDeviceFromPacket(Ethernet eth,
+            long swdpid,
+            short port) {
         byte[] dlAddrArr = eth.getSourceMACAddress();
         long dlAddr = Ethernet.toLong(dlAddrArr);
 
-        // Ignore broadcast/multicast source
-        if ((dlAddrArr[0] & 0x1) != 0) {
+        /*
+         *  Ignore broadcast/multicast source
+         */
+        if (eth.isMulticast() || eth.isBroadcast()) {
             return null;
         }
 
diff --git a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
index 5961037..81463aa 100644
--- a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
+++ b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
@@ -74,7 +74,7 @@
 
     @Override
     public synchronized void addOFMessageListener(OFType type,
-                                                  IOFMessageListener listener) {
+            IOFMessageListener listener) {
         ListenerDispatcher<OFType, IOFMessageListener> ldd =
                 listeners.get(type);
         if (ldd == null) {
@@ -86,7 +86,7 @@
 
     @Override
     public synchronized void removeOFMessageListener(OFType type,
-                                                     IOFMessageListener listener) {
+            IOFMessageListener listener) {
         ListenerDispatcher<OFType, IOFMessageListener> ldd =
                 listeners.get(type);
         if (ldd != null) {
@@ -97,11 +97,12 @@
     /**
      * @return the listeners
      */
+    @Override
     public Map<OFType, List<IOFMessageListener>> getListeners() {
         Map<OFType, List<IOFMessageListener>> lers =
                 new HashMap<OFType, List<IOFMessageListener>>();
         for (Entry<OFType, ListenerDispatcher<OFType, IOFMessageListener>> e :
-                listeners.entrySet()) {
+            listeners.entrySet()) {
             lers.put(e.getKey(), e.getValue().getOrderedListeners());
         }
         return Collections.unmodifiableMap(lers);
@@ -153,6 +154,7 @@
         }
     }
 
+    @Override
     public void handleOutgoingMessage(IOFSwitch sw, OFMessage m, FloodlightContext bc) {
         List<IOFMessageListener> msgListeners = null;
         if (listeners.containsKey(m.getType())) {
@@ -186,6 +188,7 @@
         return switchListeners;
     }
 
+    @Override
     public void terminate() {
     }
 
@@ -197,7 +200,7 @@
 
     @Override
     public boolean injectOfMessage(IOFSwitch sw, OFMessage msg,
-                                   FloodlightContext bContext) {
+            FloodlightContext bContext) {
         dispatchMessage(sw, msg, bContext);
         return true;
     }
@@ -223,10 +226,9 @@
     @Override
     public Map<Class<? extends IFloodlightService>, IFloodlightService>
     getServiceImpls() {
-        Map<Class<? extends IFloodlightService>,
-                IFloodlightService> m =
+        Map<Class<? extends IFloodlightService>, IFloodlightService> m =
                 new HashMap<Class<? extends IFloodlightService>,
-                        IFloodlightService>();
+                IFloodlightService>();
         m.put(IFloodlightProviderService.class, this);
         return m;
     }
@@ -270,7 +272,7 @@
     private void logListeners() {
         for (Map.Entry<OFType,
                 ListenerDispatcher<OFType,
-                        IOFMessageListener>> entry
+                IOFMessageListener>> entry
                 : listeners.entrySet()) {
 
             OFType type = entry.getKey();
diff --git a/src/test/java/net/onrc/onos/core/devicemanager/OnosDeviceManagerTest.java b/src/test/java/net/onrc/onos/core/devicemanager/OnosDeviceManagerTest.java
new file mode 100644
index 0000000..dd104e2
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/devicemanager/OnosDeviceManagerTest.java
@@ -0,0 +1,399 @@
+package net.onrc.onos.core.devicemanager;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.eq;
+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 java.util.Date;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IListener.Command;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IUpdate;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.test.FloodlightTestCase;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.datagrid.IDatagridService;
+import net.onrc.onos.core.datagrid.IEventChannel;
+import net.onrc.onos.core.datagrid.IEventChannelListener;
+import net.onrc.onos.core.intent.MockTopology;
+import net.onrc.onos.core.packet.ARP;
+import net.onrc.onos.core.packet.DHCP;
+import net.onrc.onos.core.packet.Data;
+import net.onrc.onos.core.packet.Ethernet;
+import net.onrc.onos.core.packet.IPacket;
+import net.onrc.onos.core.packet.IPv4;
+import net.onrc.onos.core.packet.UDP;
+import net.onrc.onos.core.registry.IControllerRegistryService;
+import net.onrc.onos.core.topology.ITopologyListener;
+import net.onrc.onos.core.topology.ITopologyService;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.openflow.protocol.OFPacketIn;
+import org.openflow.protocol.OFType;
+
+/**
+ * @author patrick.liu@huawei.com
+ *         <p/>
+ *         Unit tests for the Device Manager module (OnosDeviceManger).
+ *         These test cases check the result of add/delete device and
+ *         verify the result of processPacketIn through inject faked packets
+ *         floodLightProvider, datagridService, networkGraphService,
+ *         controllerRegistryService, eventChannel are mocked out.
+ */
+public class OnosDeviceManagerTest extends FloodlightTestCase {
+    private IPacket pkt0, pkt1, pkt2, pkt3, pkt4;
+    private IOFSwitch sw1;
+    private long sw1Dpid;
+    private short sw1DevPort;
+    private OnosDeviceManager odm;
+    private OFPacketIn pktIn;
+    private FloodlightModuleContext modContext;
+    private ITopologyService networkGraphService;
+    private IEventChannel<Long, OnosDevice> eventChannel;
+    private IFloodlightProviderService floodLightProvider;
+    private Date lastSeenTimestamp;
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        MockTopology topology = new MockTopology();
+        IDatagridService datagridService;
+        IControllerRegistryService controllerRegistryService;
+
+        topology.createSampleTopology1();
+        modContext = new FloodlightModuleContext();
+
+        floodLightProvider = createMock(IFloodlightProviderService.class);
+        datagridService = createMock(IDatagridService.class);
+        networkGraphService = createMock(ITopologyService.class);
+        controllerRegistryService = createMock(IControllerRegistryService.class);
+        eventChannel = createMock(IEventChannel.class);
+        expect(networkGraphService.getTopology()).andReturn(topology).anyTimes();
+        networkGraphService.registerTopologyListener(anyObject(ITopologyListener.class));
+        expectLastCall();
+
+        expect(datagridService.createChannel("onos.device", Long.class, OnosDevice.class))
+        .andReturn(eventChannel).once();
+        expect(topology.getOutgoingLink((long)1,(long)100)).andReturn(null).anyTimes();
+        expect(datagridService.addListener(
+                eq("onos.device"),
+                anyObject(IEventChannelListener.class),
+                eq(Long.class),
+                eq(OnosDevice.class)))
+                .andReturn(eventChannel).once();
+
+        replay(datagridService);
+        replay(networkGraphService);
+        replay(controllerRegistryService);
+
+        modContext.addService(IDatagridService.class,datagridService);
+        modContext.addService(ITopologyService.class,networkGraphService);
+        modContext.addService(IFloodlightProviderService.class, floodLightProvider);
+        modContext.getServiceImpl(IFloodlightProviderService.class);
+        sw1Dpid = 1L;
+        sw1 = createMockSwitch(sw1Dpid);
+        replay(sw1);
+
+        sw1DevPort = 100;
+
+        odm = new OnosDeviceManager();
+        /*
+         * Broadcast address
+         */
+        this.pkt0 = new Ethernet()
+        .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
+        .setSourceMACAddress("00:44:33:22:11:33")
+        .setEtherType(Ethernet.TYPE_IPV4)
+        .setPayload(
+                new IPv4()
+                .setTtl((byte) 128)
+                .setSourceAddress("192.168.10.1")
+                .setDestinationAddress("192.168.255.255")
+                .setPayload(new UDP()
+                .setSourcePort((short) 5000)
+                .setDestinationPort((short) 5001)
+                .setPayload(new Data(new byte[]{0x01}))));
+        /*
+         * Normal IPv4 packet
+         */
+        this.pkt1 = new Ethernet()
+        .setDestinationMACAddress("00:11:22:33:44:55")
+        .setSourceMACAddress("00:44:33:22:11:00")
+        .setEtherType(Ethernet.TYPE_IPV4)
+        .setPayload(
+                new IPv4()
+                .setTtl((byte) 128)
+                .setSourceAddress("192.168.1.1")
+                .setDestinationAddress("192.168.1.2")
+                .setPayload(new UDP()
+                .setSourcePort((short) 5000)
+                .setDestinationPort((short) 5001)
+                .setPayload(new Data(new byte[]{0x01}))));
+        /*
+         * Same MAC header as pkt1,but not IP address set
+         */
+        this.pkt2 = new Ethernet()
+        .setSourceMACAddress("00:44:33:22:11:01")
+        .setDestinationMACAddress("00:11:22:33:44:55")
+        .setEtherType(Ethernet.TYPE_IPV4)
+        .setPayload(
+                new IPv4()
+                .setTtl((byte) 128)
+                .setPayload(new UDP()
+                .setSourcePort((short) 5000)
+                .setDestinationPort((short) 5001)
+                .setPayload(new Data(new byte[]{0x01}))));
+        /*
+         * DHCP packet
+         */
+        this.pkt3 = new Ethernet()
+        .setSourceMACAddress("00:44:33:22:11:01")
+        .setDestinationMACAddress("00:11:22:33:44:55")
+        .setEtherType(Ethernet.TYPE_IPV4)
+        .setPayload(
+                new IPv4()
+                .setTtl((byte) 128)
+                .setSourceAddress("192.168.1.1")
+                .setDestinationAddress("192.168.1.2")
+                .setPayload(new UDP()
+                .setSourcePort((short) 5000)
+                .setDestinationPort((short) 5001)
+                .setChecksum((short) 0)
+                .setPayload(
+                        new DHCP()
+                        .setOpCode(DHCP.OPCODE_REPLY)
+                        .setHardwareType(DHCP.HWTYPE_ETHERNET)
+                        .setHardwareAddressLength((byte) 6)
+                        .setHops((byte) 0)
+                        .setTransactionId(0x00003d1d)
+                        .setSeconds((short) 0)
+                        .setFlags((short) 0)
+                        .setClientIPAddress(0)
+                        .setYourIPAddress(0)
+                        .setServerIPAddress(0)
+                        .setGatewayIPAddress(0))));
+        /*
+         * ARP packet
+         */
+        this.pkt4 = new Ethernet()
+        .setSourceMACAddress("00:44:33:22:11:01")
+        .setDestinationMACAddress("00:11:22:33:44:55")
+        .setEtherType(Ethernet.TYPE_ARP)
+        .setPayload(
+                new ARP()
+                .setHardwareType(ARP.HW_TYPE_ETHERNET)
+                .setProtocolType(ARP.PROTO_TYPE_IP)
+                .setHardwareAddressLength((byte) 6)
+                .setProtocolAddressLength((byte) 4)
+                .setOpCode(ARP.OP_REPLY)
+                .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
+                .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
+                .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
+                .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
+
+
+        this.pktIn = new OFPacketIn()
+        .setInPort(sw1DevPort);
+
+        lastSeenTimestamp = new Date(1);
+
+        odm.init(modContext);
+        odm.startUp(modContext);
+    }
+
+    @Override
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    public IOFSwitch createMockSwitch(Long id) {
+        IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
+        expect(mockSwitch.getId()).andReturn(id).anyTimes();
+        return mockSwitch;
+    }
+
+    /**
+     * Test set operation on lastSeenTimstamp field in OnosDevice
+     */
+    @Test
+    public void testSetLastSeenTimestamp() {
+        Ethernet eth = (Ethernet)pkt1;
+        OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
+
+        floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
+        srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
+        assertEquals(lastSeenTimestamp, srcDevice.getLastSeenTimestamp());
+    }
+    /**
+     * test the functionality to get the source device from Packet header
+     * information.
+     */
+    @Test
+    public void testGetSourceDeviceFromPacket() {
+        byte[] address = new byte[] {0x00,0x44,0x33,0x22,0x11,0x01};
+        MACAddress srcMac = new MACAddress(address);
+        IPv4 v4Pkt = new IPv4()
+        .setSourceAddress("192.168.1.1")
+        .setDestinationAddress("192.168.1.2");
+        OnosDevice dev1 = new OnosDevice(srcMac,
+                null,
+                v4Pkt.getSourceAddress(),
+                sw1Dpid,
+                sw1DevPort,
+                null);
+
+        /*
+         * test DHCP packet case
+         */
+        Ethernet eth = (Ethernet)pkt3;
+        OnosDevice dev2 = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
+        assertEquals(dev1, dev2);
+
+        /*
+         * test ARP packet case
+         */
+        eth = (Ethernet)pkt4;
+        dev2 = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
+        assertEquals(dev1, dev2);
+    }
+
+    /**
+     * This test will invoke addOnosDevice to add a new device through Packet pkt1
+     */
+    @Test
+    public void testProcessPacketInAddNewDevice() {
+        Ethernet eth = (Ethernet)pkt1;
+        Long longmac = eth.getSourceMAC().toLong();
+        OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
+
+        floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
+        EasyMock.expectLastCall();
+        eventChannel.addEntry(longmac, srcDevice);
+        EasyMock.expectLastCall();
+        floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
+        EasyMock.expectLastCall();
+        replay(floodLightProvider, eventChannel);
+
+        Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt1);
+        assertEquals(Command.CONTINUE, cmd);
+
+        verify(eventChannel);
+    }
+
+    /**
+     * This test will test return Command.STOP path in processPacketIn method
+     * by injecting a broadcast packet
+     */
+    @Test
+    public void testProcessPacketInStop() {
+        Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt0);
+        assertEquals(Command.STOP, cmd);
+    }
+
+    /**
+     * This tests same packet received case.
+     */
+    @Test
+    public void testProcessPacketInSamePacket() {
+        Ethernet eth = (Ethernet)pkt2;
+        OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
+        odm.entryAdded(srcDevice);
+        srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
+
+        Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt2);
+        assertEquals(Command.CONTINUE, cmd);
+        assertTrue(lastSeenTimestamp.before(srcDevice.getLastSeenTimestamp()));
+    }
+
+    /**
+     * This tests the packet with the same MAC but the second one without IP address
+     */
+    @Test
+    public void testProcessPacketInNoIpAddress() {
+        Ethernet eth = (Ethernet)pkt3;
+        OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
+        odm.entryAdded(srcDevice);
+        srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
+
+        Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt2);
+        assertEquals(Command.CONTINUE, cmd);
+        assertTrue(lastSeenTimestamp.before(srcDevice.getLastSeenTimestamp()));
+    }
+
+    /**
+     * Test add a device from the information from packet
+     */
+    @Test
+    public void testAddOnosDevice() {
+        Ethernet eth = (Ethernet)pkt1;
+        Long longmac = eth.getSourceMAC().toLong();
+        OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
+
+        floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
+        EasyMock.expectLastCall();
+        eventChannel.addEntry(longmac, srcDevice);
+        EasyMock.expectLastCall();
+        floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
+        EasyMock.expectLastCall();
+        replay(floodLightProvider, eventChannel);
+
+        odm.addOnosDevice(longmac, srcDevice);
+
+        verify(eventChannel);
+    }
+
+    /**
+     * Test delete a device
+     */
+    @Test
+    public void testDeleteOnosDevice() {
+        Ethernet eth = (Ethernet)pkt1;
+        Long longmac = eth.getSourceMAC().toLong();
+        OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
+
+        floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
+        EasyMock.expectLastCall();
+        eventChannel.removeEntry(longmac);
+        EasyMock.expectLastCall();
+        floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
+        EasyMock.expectLastCall();
+        replay(floodLightProvider, eventChannel);
+
+        odm.deleteOnosDevice(srcDevice);
+
+        verify(eventChannel);
+    }
+
+    /**
+     * Test delete a device by using its source mac address
+     */
+    @Test
+    public void testDeleteOnosDeviceByMac() {
+        Ethernet eth = (Ethernet)pkt1;
+        MACAddress mac = eth.getSourceMAC();
+        Long longmac = mac.toLong();
+        OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
+
+        floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
+        EasyMock.expectLastCall();
+        eventChannel.removeEntry(longmac);
+        EasyMock.expectLastCall();
+        floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
+        EasyMock.expectLastCall();
+        replay(floodLightProvider, eventChannel);
+
+        odm.entryAdded(srcDevice);
+        odm.deleteOnosDeviceByMac(mac);
+        verify(eventChannel);
+    }
+}
