diff --git a/app/src/test/java/org/opencord/igmpproxy/impl/IgmpManagerBase.java b/app/src/test/java/org/opencord/igmpproxy/impl/IgmpManagerBase.java
new file mode 100644
index 0000000..b301f94
--- /dev/null
+++ b/app/src/test/java/org/opencord/igmpproxy/impl/IgmpManagerBase.java
@@ -0,0 +1,682 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.opencord.igmpproxy.impl;
+
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IGMP;
+import org.onlab.packet.IGMPMembership;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.cfg.ConfigProperty;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.event.DefaultEventSinkRegistry;
+import org.onosproject.event.Event;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.event.EventSink;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.mcast.api.McastListener;
+import org.onosproject.mcast.api.McastRoute;
+import org.onosproject.mcast.api.McastRouteData;
+import org.onosproject.mcast.api.MulticastRouteService;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.net.config.basics.McastConfig;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.DefaultPacketContext;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketServiceAdapter;
+import org.opencord.sadis.BandwidthProfileInformation;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentInstance;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+public class IgmpManagerBase {
+
+    // Device configuration
+    protected static final DeviceId DEVICE_ID_OF_A = DeviceId.deviceId("of:1");
+    protected static final DeviceId DEVICE_ID_OF_B = DeviceId.deviceId("of:2");
+    protected static final DeviceId DEVICE_ID_OF_C = DeviceId.deviceId("of:00000000000000003");
+
+    //Multicast ip address
+    protected static final Ip4Address GROUP_IP = Ip4Address.valueOf("224.0.0.0");
+    //Unknown group Ip address
+    protected static final Ip4Address UNKNOWN_GRP_IP = Ip4Address.valueOf("124.0.0.0");
+    // Source ip address of two different device.
+    protected static final Ip4Address SOURCE_IP_OF_A = Ip4Address.valueOf("10.177.125.4");
+    protected static final Ip4Address SOURCE_IP_OF_B = Ip4Address.valueOf("10.177.125.5");
+
+    // Common connect point of aggregation switch used by all devices.
+    protected static final ConnectPoint COMMON_CONNECT_POINT =
+           ConnectPoint.deviceConnectPoint("of:00000000000000003/3");
+    // Uplink ports for two olts A and B
+    protected static final PortNumber PORT_A = PortNumber.portNumber(1);
+    protected static final PortNumber PORT_B = PortNumber.portNumber(2);
+    protected static final PortNumber PORT_C = PortNumber.portNumber(3);
+    protected static final PortNumber PORT_NNI = PortNumber.portNumber(65536);
+
+    // Connect Point mode for two olts
+    protected static final ConnectPoint CONNECT_POINT_A = new ConnectPoint(DEVICE_ID_OF_A, PORT_A);
+    protected static final ConnectPoint CONNECT_POINT_B = new ConnectPoint(DEVICE_ID_OF_B, PORT_B);
+    protected static final ConnectPoint CONNECT_POINT_C = new ConnectPoint(DEVICE_ID_OF_C, PORT_C);
+
+    protected static final String CLIENT_NAS_PORT_ID = "PON 1/1";
+    protected static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
+    protected String dsBpId = "HSIA-DS";
+
+    private static final int STATISTICS_GEN_PERIOD_IN_SEC = 2;
+
+    private static final String NNI_PREFIX = "nni";
+
+    protected List<Port> lsPorts = new ArrayList<Port>();
+    protected List<Device> lsDevices = new ArrayList<Device>();
+    // Flag for adding two different devices in oltData
+    protected boolean flagForDevice = true;
+    PacketContext context;
+    // Flag for sending two different packets
+    protected boolean flagForPacket = true;
+    // Flag for sending two different packets
+    protected boolean flagForQueryPacket = false;
+    // Flag to check permission
+    boolean flagForPermission = false;
+    // List to store the packets emitted
+    protected List<OutboundPacket> savedPackets;
+    protected PacketProcessor packetProcessor;
+
+    class MockDeviceService extends DeviceServiceAdapter {
+
+        @Override
+        public Device getDevice(DeviceId deviceId) {
+           if (flagForDevice) {
+               DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
+                           .set(AnnotationKeys.MANAGEMENT_ADDRESS, SOURCE_IP_OF_A.toString());
+               SparseAnnotations annotations = annotationsBuilder.build();
+               Annotations[] da = {annotations };
+               Device deviceA = new DefaultDevice(null, DEVICE_ID_OF_A, Device.Type.OTHER, "", "", "", "", null, da);
+               flagForDevice = false;
+               return deviceA;
+            } else {
+               DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
+                          .set(AnnotationKeys.MANAGEMENT_ADDRESS, SOURCE_IP_OF_B.toString());
+               SparseAnnotations annotations = annotationsBuilder.build();
+               Annotations[] da = {annotations };
+               Device deviceB = new DefaultDevice(null, DEVICE_ID_OF_B, Device.Type.OTHER, "", "", "", "", null, da);
+               return deviceB;
+           }
+        }
+        @Override
+        public List<Port> getPorts(DeviceId deviceId) {
+            return lsPorts;
+        }
+
+        @Override
+        public Iterable<Device> getAvailableDevices() {
+            DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
+                    .set(AnnotationKeys.MANAGEMENT_ADDRESS, SOURCE_IP_OF_A.toString());
+            SparseAnnotations annotations = annotationsBuilder.build();
+            Annotations[] da = {annotations };
+            Device deviceA = new DefaultDevice(null, DEVICE_ID_OF_C, Device.Type.OTHER, "", "", "", "", null, da);
+            lsDevices.add(deviceA);
+            return lsDevices;
+        }
+
+        @Override
+        public Port getPort(DeviceId deviceId, PortNumber portNumber) {
+            if (portNumber.equals(PORT_NNI)) {
+                DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
+                        .set(AnnotationKeys.PORT_NAME, NNI_PREFIX);
+                Port nni = new DefaultPort(null, portNumber, true, annotationsBuilder.build());
+                return nni;
+            }
+            return super.getPort(deviceId, portNumber);
+        }
+    }
+
+    static final Class<IgmpproxyConfig> IGMPPROXY_CONFIG_CLASS = IgmpproxyConfig.class;
+    static final Class<IgmpproxySsmTranslateConfig> IGMPPROXY_SSM_CONFIG_CLASS = IgmpproxySsmTranslateConfig.class;
+    static final Class<McastConfig> MCAST_CONFIG_CLASS = McastConfig.class;
+    ConfigFactory<ApplicationId, IgmpproxyConfig> igmpproxyConfigFactory =
+         new ConfigFactory<ApplicationId, IgmpproxyConfig>(
+        SubjectFactories.APP_SUBJECT_FACTORY, IGMPPROXY_CONFIG_CLASS, "igmpproxy") {
+    @Override
+    public IgmpproxyConfig createConfig() {
+          return new IgmpproxyConfig();
+        }
+    };
+
+    ConfigFactory<ApplicationId, IgmpproxySsmTranslateConfig> igmpproxySsmConfigFactory =
+        new ConfigFactory<ApplicationId, IgmpproxySsmTranslateConfig>(
+        SubjectFactories.APP_SUBJECT_FACTORY, IGMPPROXY_SSM_CONFIG_CLASS, "ssmTranslate", true) {
+
+        @Override
+        public IgmpproxySsmTranslateConfig createConfig() {
+            return new IgmpproxySsmTranslateConfig();
+        }
+    };
+
+
+    class MockIgmpProxyConfig extends IgmpproxyConfig {
+        boolean igmpOnPodBasis = true;
+
+        MockIgmpProxyConfig(boolean igmpFlagValue) {
+           igmpOnPodBasis = igmpFlagValue;
+       }
+        @Override
+        public boolean igmpOnPodBasis() {
+            return igmpOnPodBasis;
+        }
+
+        @Override
+        public ConnectPoint getSourceDeviceAndPort() {
+            if (flagForPermission) {
+                return null;
+            }
+            return COMMON_CONNECT_POINT;
+        }
+
+        @Override
+        public ConnectPoint connectPoint() {
+               return COMMON_CONNECT_POINT;
+        }
+    }
+
+
+     class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
+         Boolean igmpOnPodFlag = false;
+
+         TestNetworkConfigRegistry(Boolean igmpFlag) {
+             igmpOnPodFlag = igmpFlag;
+         }
+        @SuppressWarnings("unchecked")
+        @Override
+        public <S> Set<S> getSubjects(Class<S> subjectClass) {
+            if (subjectClass.getName().equalsIgnoreCase("org.onosproject.net.DeviceId")) {
+                return (Set<S>) ImmutableSet.of(DEVICE_ID_OF_A, DEVICE_ID_OF_B);
+            }
+            return null;
+       }
+
+         @SuppressWarnings("unchecked")
+         @Override
+         public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+             if (configClass.getName().equalsIgnoreCase("org.opencord.igmpproxy.impl.IgmpproxyConfig")) {
+                 IgmpproxyConfig igmpproxyConfig = new MockIgmpProxyConfig(igmpOnPodFlag);
+                 return (C) igmpproxyConfig;
+             } else {
+                 super.getConfig(subject, configClass);
+             }
+             return null;
+         }
+    }
+
+
+    /**
+     * Keeps a reference to the PacketProcessor and saves the OutboundPackets. Adds
+     * the emitted packet in savedPackets list
+     */
+    class MockPacketService extends PacketServiceAdapter {
+
+        public MockPacketService() {
+            savedPackets = new LinkedList<>();
+        }
+
+        @Override
+        public void addProcessor(PacketProcessor processor, int priority) {
+            packetProcessor = processor;
+        }
+
+        @Override
+        public void emit(OutboundPacket packet) {
+            synchronized (savedPackets) {
+               savedPackets.add(packet);
+               savedPackets.notify();
+            }
+        }
+     }
+
+
+    class MockMastershipService extends MastershipServiceAdapter {
+        @Override
+        public boolean isLocalMaster(DeviceId deviceId) {
+            return true;
+        }
+    }
+
+    final class TestMulticastRouteService implements MulticastRouteService {
+        @Override
+        public void addListener(McastListener listener) {
+        }
+
+        @Override
+        public void removeListener(McastListener listener) {
+        }
+
+        @Override
+        public void add(McastRoute route) {
+        }
+
+        @Override
+        public void remove(McastRoute route) {
+        }
+
+        @Override
+        public Set<McastRoute> getRoutes() {
+            return null;
+        }
+
+        @Override
+        public Set<McastRoute> getRoute(IpAddress groupIp, IpAddress sourceIp) {
+            return null;
+        }
+
+        @Override
+        public void addSource(McastRoute route, HostId source) {
+        }
+
+        @Override
+        public void addSources(McastRoute route, HostId hostId, Set<ConnectPoint> connectPoints) {
+        }
+
+        @Override
+        public void addSources(McastRoute route, Set<ConnectPoint> sources) {
+
+        }
+
+        @Override
+        public void removeSources(McastRoute route) {
+
+        }
+
+        @Override
+        public void removeSource(McastRoute route, HostId source) {
+
+        }
+
+        @Override
+        public void addSink(McastRoute route, HostId hostId) {
+
+        }
+
+        @Override
+        public void addSinks(McastRoute route, HostId hostId, Set<ConnectPoint> connectPoints) {
+
+        }
+
+        @Override
+        public void addSinks(McastRoute route, Set<ConnectPoint> sinks) {
+
+        }
+
+        @Override
+        public void removeSinks(McastRoute route) {
+
+        }
+
+        @Override
+        public void removeSink(McastRoute route, HostId hostId) {
+
+        }
+
+        @Override
+        public void removeSinks(McastRoute route, Set<ConnectPoint> sink) {
+
+        }
+
+        @Override
+        public McastRouteData routeData(McastRoute route) {
+            return null;
+        }
+
+        @Override
+        public Set<ConnectPoint> sources(McastRoute route) {
+            return null;
+        }
+
+        @Override
+        public Set<ConnectPoint> sources(McastRoute route, HostId hostId) {
+            return null;
+        }
+
+        @Override
+        public Set<ConnectPoint> sinks(McastRoute route) {
+            return null;
+        }
+
+        @Override
+        public Set<ConnectPoint> sinks(McastRoute route, HostId hostId) {
+            return null;
+        }
+
+        @Override
+        public Set<ConnectPoint> nonHostSinks(McastRoute route) {
+            return null;
+        }
+
+    }
+
+
+    /**
+     * Mocks the DefaultPacketContext.
+     */
+    final class TestPacketContext extends DefaultPacketContext {
+       TestPacketContext(long time, InboundPacket inPkt, OutboundPacket outPkt, boolean block) {
+         super(time, inPkt, outPkt, block);
+         }
+
+        @Override
+        public void send() {
+            // We don't send anything out.
+        }
+    }
+
+    /**
+     * Sends Ethernet packet to the process method of the Packet Processor.
+     *
+     * @param reply Ethernet packet
+     * @throws InterruptedException
+     */
+     void sendPacket(Ethernet reply) {
+
+         if (reply != null) {
+             final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
+
+             if (flagForQueryPacket) {
+                 InboundPacket inBoundPacket = new DefaultInboundPacket(CONNECT_POINT_C, reply, byteBuffer);
+                 context = new TestPacketContext(127L, inBoundPacket, null, false);
+                 packetProcessor.process(context);
+             } else {
+                 if (flagForPacket) {
+                     InboundPacket inPacket = new DefaultInboundPacket(CONNECT_POINT_A, reply, byteBuffer);
+                     context = new TestPacketContext(127L, inPacket, null, false);
+                     flagForPacket = false;
+
+                     packetProcessor.process(context);
+                 } else {
+                     InboundPacket inBoundPacket = new DefaultInboundPacket(CONNECT_POINT_B, reply, byteBuffer);
+                     context = new TestPacketContext(127L, inBoundPacket, null, false);
+                     flagForPacket = true;
+
+                     packetProcessor.process(context);
+                 }
+             }
+         }
+    }
+
+    protected class MockSadisService implements SadisService {
+
+        @Override
+        public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
+            return new MockSubService();
+        }
+
+        @Override
+        public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
+            return new MockBpService();
+        }
+    }
+
+    private class MockBpService implements BaseInformationService<BandwidthProfileInformation> {
+
+        @Override
+        public void invalidateAll() {
+
+        }
+
+        @Override
+        public void invalidateId(String id) {
+
+        }
+
+        @Override
+        public BandwidthProfileInformation get(String id) {
+            if (id.equals(dsBpId)) {
+                BandwidthProfileInformation bpInfo = new BandwidthProfileInformation();
+                bpInfo.setAssuredInformationRate(0);
+                bpInfo.setCommittedInformationRate(10000);
+                bpInfo.setCommittedBurstSize(1000L);
+                bpInfo.setExceededBurstSize(2000L);
+                bpInfo.setExceededInformationRate(20000);
+                return bpInfo;
+            }
+            return null;
+        }
+
+        @Override
+        public BandwidthProfileInformation getfromCache(String id) {
+            return null;
+        }
+    }
+
+    private class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
+        MockSubscriberAndDeviceInformation sub =
+                new MockSubscriberAndDeviceInformation(CLIENT_NAS_PORT_ID,
+                                                       CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null);
+
+        @Override
+        public SubscriberAndDeviceInformation get(String id) {
+            return sub;
+        }
+
+        @Override
+        public void invalidateAll() {
+        }
+
+        @Override
+        public void invalidateId(String id) {
+        }
+
+        @Override
+        public SubscriberAndDeviceInformation getfromCache(String id) {
+            return null;
+        }
+    }
+
+    private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
+
+        MockSubscriberAndDeviceInformation(String id, String nasPortId,
+                                           String circuitId, MacAddress hardId,
+                                           Ip4Address ipAddress) {
+            this.setHardwareIdentifier(hardId);
+            this.setId(id);
+            this.setIPAddress(ipAddress);
+            this.setNasPortId(nasPortId);
+            this.setCircuitId(circuitId);
+            this.setUplinkPort((int) PORT_NNI.toLong());
+        }
+    }
+
+    protected class MockCfgService implements ComponentConfigService {
+
+        @Override
+        public Set<String> getComponentNames() {
+            return null;
+        }
+
+        @Override
+        public void registerProperties(Class<?> componentClass) {
+
+        }
+
+        @Override
+        public void unregisterProperties(Class<?> componentClass, boolean clear) {
+
+        }
+
+        @Override
+        public Set<ConfigProperty> getProperties(String componentName) {
+            return null;
+        }
+
+        @Override
+        public void setProperty(String componentName, String name, String value) {
+
+        }
+
+        @Override
+        public void preSetProperty(String componentName, String name, String value) {
+
+        }
+
+        @Override
+        public void preSetProperty(String componentName, String name, String value, boolean override) {
+
+        }
+
+        @Override
+        public void unsetProperty(String componentName, String name) {
+
+        }
+
+        @Override
+        public ConfigProperty getProperty(String componentName, String attribute) {
+            return null;
+        }
+
+    }
+
+    public static class TestEventDispatcher extends DefaultEventSinkRegistry implements EventDeliveryService {
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public synchronized void post(Event event) {
+            EventSink sink = getSink(event.getClass());
+            checkState(sink != null, "No sink for event %s", event);
+            sink.process(event);
+        }
+
+        @Override
+        public void setDispatchTimeLimit(long millis) {
+        }
+
+        @Override
+        public long getDispatchTimeLimit() {
+            return 0;
+        }
+    }
+
+    class MockComponentContext implements ComponentContext {
+
+        @Override
+        public Dictionary<String, Object> getProperties() {
+            Dictionary<String, Object> cfgDict = new Hashtable<String, Object>();
+            cfgDict.put("statisticsGenerationPeriodInSeconds", STATISTICS_GEN_PERIOD_IN_SEC);
+            return cfgDict;
+        }
+
+        @Override
+        public Object locateService(String name) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Object locateService(String name, ServiceReference reference) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Object[] locateServices(String name) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public BundleContext getBundleContext() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Bundle getUsingBundle() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public ComponentInstance getComponentInstance() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public void enableComponent(String name) {
+            // TODO Auto-generated method stub
+        }
+
+        @Override
+         public void disableComponent(String name) {
+             // TODO Auto-generated method stub
+         }
+
+         @Override
+         public ServiceReference getServiceReference() {
+             // TODO Auto-generated method stub
+             return null;
+         }
+    }
+
+    Ethernet buildWrongIgmpPacket(Ip4Address groupIp, Ip4Address sourceIp) {
+        IGMPMembership igmpMembership = new IGMPMembership(groupIp);
+        igmpMembership.setRecordType((byte) 0x33);
+
+        return IgmpSender.getInstance().buildIgmpPacket(IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT, groupIp,
+            igmpMembership, sourceIp, false);
+    }
+
+    Ethernet buildUnknownIgmpPacket(Ip4Address groupIp, Ip4Address sourceIp) {
+        IGMPMembership igmpMembership = new IGMPMembership(groupIp);
+        igmpMembership.setRecordType((byte) 0x33);
+
+        return IgmpSender.getInstance().buildIgmpPacket((byte) 0x44, groupIp, igmpMembership, sourceIp, false);
+    }
+
+}
diff --git a/app/src/test/java/org/opencord/igmpproxy/impl/IgmpManagerTest.java b/app/src/test/java/org/opencord/igmpproxy/impl/IgmpManagerTest.java
new file mode 100644
index 0000000..dc220f8
--- /dev/null
+++ b/app/src/test/java/org/opencord/igmpproxy/impl/IgmpManagerTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.opencord.igmpproxy.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.Ethernet;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.net.flow.FlowRuleServiceAdapter;
+import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
+import org.opencord.igmpproxy.impl.IgmpManagerBase.MockComponentContext;
+
+import static org.junit.Assert.*;
+
+/**
+ * Set of tests of the ONOS application component.
+ */
+public class IgmpManagerTest extends IgmpManagerBase {
+
+    private static final int WAIT_TIMEOUT = 1000;
+
+    private IgmpManager igmpManager;
+
+    private IgmpStatisticsManager igmpStatisticsManager;
+
+    // Set up the IGMP application.
+    @Before
+    public void setUp() {
+        igmpManager = new IgmpManager();
+        igmpManager.coreService = new CoreServiceAdapter();
+        igmpManager.mastershipService = new MockMastershipService();
+        igmpManager.flowObjectiveService = new FlowObjectiveServiceAdapter();
+        igmpManager.deviceService = new MockDeviceService();
+        igmpManager.packetService = new MockPacketService();
+        igmpManager.flowRuleService = new FlowRuleServiceAdapter();
+        igmpManager.multicastService = new TestMulticastRouteService();
+        igmpManager.sadisService = new MockSadisService();
+        igmpStatisticsManager = new IgmpStatisticsManager();
+        igmpStatisticsManager.cfgService = new MockCfgService();
+        TestUtils.setField(igmpStatisticsManager, "eventDispatcher", new TestEventDispatcher());
+        igmpStatisticsManager.activate(new MockComponentContext());
+        igmpManager.igmpStatisticsManager = this.igmpStatisticsManager;
+        // By default - we send query messages
+        SingleStateMachine.sendQuery = true;
+    }
+
+    // Tear Down the IGMP application.
+    @After
+    public void tearDown() {
+        igmpManager.deactivate();
+        IgmpManager.groupMemberMap.clear();
+        StateMachine.clearMap();
+    }
+
+    // Checking the Default value of IGMP_ON_POD_BASIS.
+    @Test
+    public void testIsIgmpOnPodBasisDefaultValue() {
+        igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
+        igmpManager.activate();
+        assertFalse(IgmpManager.isIgmpOnPodBasis());
+    }
+
+
+    // Checking the value of IGMP_ON_POD_BASIS.
+    @Test
+    public void testIsIgmpOnPodBasisTrueValue() {
+        igmpManager.networkConfig = new TestNetworkConfigRegistry(true);
+        igmpManager.activate();
+        assertTrue(IgmpManager.isIgmpOnPodBasis());
+    }
+
+    // Testing the flow of packet when isIgmpOnPodBasis value is false.
+    @Test
+    public void testIgmpOnPodBasisDefaultValue() throws InterruptedException {
+        // We need to count join messages sent on the upstream
+        SingleStateMachine.sendQuery = false;
+
+        igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
+        igmpManager.activate();
+
+        Ethernet firstPacket = IgmpSender.getInstance().buildIgmpV3Join(GROUP_IP, SOURCE_IP_OF_A);
+        Ethernet secondPacket = IgmpSender.getInstance().buildIgmpV3Join(GROUP_IP, SOURCE_IP_OF_B);
+        // Sending first packet and here shouldSendjoin flag will be true
+        sendPacket(firstPacket);
+        // Emitted packet is stored in list savedPackets
+        assertNotNull(savedPackets);
+        synchronized (savedPackets) {
+            savedPackets.wait(WAIT_TIMEOUT);
+        }
+
+        assertNotNull(savedPackets);
+        assertEquals(1, savedPackets.size());
+        // Sending the second packet with same group ip address
+        sendPacket(secondPacket);
+        synchronized (savedPackets) {
+            savedPackets.wait(WAIT_TIMEOUT);
+        }
+        // Emitted packet is stored in list savedPackets as shouldSendJoin flag is true
+        assertEquals(2, savedPackets.size());
+    }
+
+    // Testing IGMP_ON_POD_BASIS value by sending two packets.
+    @Test
+    public void testIgmpOnPodBasisTrueValue() throws InterruptedException {
+        // We need to count join messages
+        SingleStateMachine.sendQuery = false;
+
+        igmpManager.networkConfig = new TestNetworkConfigRegistry(true);
+        igmpManager.activate();
+
+        Ethernet firstPacket = IgmpSender.getInstance().buildIgmpV3Join(GROUP_IP, SOURCE_IP_OF_A);
+        Ethernet secondPacket = IgmpSender.getInstance().buildIgmpV3Join(GROUP_IP, SOURCE_IP_OF_B);
+        // Sending first packet and here shouldSendjoin flag will be true
+        sendPacket(firstPacket);
+        // Emitted packet is stored in list savedPackets
+        synchronized (savedPackets) {
+          savedPackets.wait(WAIT_TIMEOUT);
+        }
+        assertNotNull(savedPackets);
+        assertEquals(1, savedPackets.size());
+        // Sending the second packet with same group ip address which will not be emitted
+        // shouldSendJoin flag will be false.
+        sendPacket(secondPacket);
+        synchronized (savedPackets) {
+            savedPackets.wait(WAIT_TIMEOUT);
+        }
+        assertEquals(1, savedPackets.size());
+    }
+
+}
diff --git a/app/src/test/java/org/opencord/igmpproxy/impl/IgmpStatisticsTest.java b/app/src/test/java/org/opencord/igmpproxy/impl/IgmpStatisticsTest.java
new file mode 100644
index 0000000..2677511
--- /dev/null
+++ b/app/src/test/java/org/opencord/igmpproxy/impl/IgmpStatisticsTest.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.opencord.igmpproxy.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.onlab.junit.TestTools.assertAfter;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.net.flow.FlowRuleServiceAdapter;
+import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
+
+import org.opencord.igmpproxy.IgmpStatisticsEvent;
+
+import com.google.common.collect.Lists;
+import org.opencord.igmpproxy.IgmpStatisticsEventListener;
+
+/**
+ * Set of tests of the ONOS application component for IGMP Statistics.
+ */
+public class IgmpStatisticsTest extends IgmpManagerBase {
+
+    private static final int WAIT_TIMEOUT = 500;
+
+    private IgmpManager igmpManager;
+
+    private IgmpStatisticsManager igmpStatisticsManager;
+
+    private MockIgmpStatisticsEventListener mockListener = new MockIgmpStatisticsEventListener();
+
+    // Set up the IGMP application.
+    @Before
+    public void setUp() {
+        igmpManager = new IgmpManager();
+        igmpManager.coreService = new CoreServiceAdapter();
+        igmpManager.mastershipService = new MockMastershipService();
+        igmpManager.flowObjectiveService = new FlowObjectiveServiceAdapter();
+        igmpManager.deviceService = new MockDeviceService();
+        igmpManager.packetService = new MockPacketService();
+        igmpManager.flowRuleService = new FlowRuleServiceAdapter();
+        igmpManager.multicastService = new TestMulticastRouteService();
+        igmpManager.sadisService = new MockSadisService();
+        igmpStatisticsManager = new IgmpStatisticsManager();
+        igmpStatisticsManager.cfgService = new MockCfgService();
+        igmpStatisticsManager.addListener(mockListener);
+        TestUtils.setField(igmpStatisticsManager, "eventDispatcher", new TestEventDispatcher());
+        igmpStatisticsManager.activate(new MockComponentContext());
+        igmpManager.igmpStatisticsManager = this.igmpStatisticsManager;
+        // By default - we send query messages
+        SingleStateMachine.sendQuery = true;
+    }
+
+    // Tear Down the IGMP application.
+    @After
+    public void tearDown() {
+        igmpStatisticsManager.removeListener(mockListener);
+        igmpStatisticsManager.deactivate();
+        IgmpManager.groupMemberMap.clear();
+        StateMachine.clearMap();
+    }
+
+    //Test Igmp Statistics.
+    @Test
+    public void testIgmpStatistics() throws InterruptedException {
+        SingleStateMachine.sendQuery = false;
+        igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
+        igmpManager.activate();
+
+        //IGMPv3 Join
+        flagForPacket = false;
+        Ethernet igmpv3MembershipReportPkt = IgmpSender.getInstance().buildIgmpV3Join(GROUP_IP, SOURCE_IP_OF_A);
+        sendPacket(igmpv3MembershipReportPkt);
+        synchronized (savedPackets) {
+            savedPackets.wait(WAIT_TIMEOUT);
+        }
+        //Leave
+        flagForPacket = false;
+        Ethernet igmpv3LeavePkt = IgmpSender.getInstance().buildIgmpV3Leave(GROUP_IP, SOURCE_IP_OF_A);
+        sendPacket(igmpv3LeavePkt);
+        synchronized (savedPackets) {
+            savedPackets.wait(WAIT_TIMEOUT);
+        }
+
+        assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
+            assertEquals((long) 2, igmpStatisticsManager.getIgmpStats().getTotalMsgReceived().longValue()));
+        assertEquals((long) 1, igmpStatisticsManager.getIgmpStats().getIgmpJoinReq().longValue());
+        assertEquals((long) 2, igmpStatisticsManager.getIgmpStats().getIgmpv3MembershipReport().longValue());
+        assertEquals((long) 1, igmpStatisticsManager.getIgmpStats().getIgmpSuccessJoinRejoinReq().longValue());
+        assertEquals((long) 1, igmpStatisticsManager.getIgmpStats().getUnconfiguredGroupCounter().longValue());
+        assertEquals((long) 2, igmpStatisticsManager.getIgmpStats().getValidIgmpPacketCounter().longValue());
+        assertEquals((long) 1, igmpStatisticsManager.getIgmpStats().getIgmpChannelJoinCounter().longValue());
+        assertEquals((long) 1, igmpStatisticsManager.getIgmpStats().getIgmpLeaveReq().longValue());
+        assertEquals((long) 2, igmpStatisticsManager.getIgmpStats().getIgmpMsgReceived().longValue());
+        assertEquals((long) 2, igmpStatisticsManager.getIgmpStats().getIgmpValidChecksumCounter().longValue());
+
+    }
+
+    //Test packet with Unknown Multicast IpAddress
+    @Test
+    public void testIgmpUnknownMulticastIpAddress() throws InterruptedException {
+        SingleStateMachine.sendQuery = false;
+
+        igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
+        igmpManager.activate();
+
+        Ethernet firstPacket =
+             IgmpSender.getInstance().buildIgmpV3Join(UNKNOWN_GRP_IP, SOURCE_IP_OF_A);
+        // Sending first packet
+        sendPacket(firstPacket);
+        assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
+        assertEquals((long) 1,
+             igmpStatisticsManager.getIgmpStats().getFailJoinReqUnknownMulticastIpCounter().longValue()));
+    }
+
+    //Test Igmp Query Statistics.
+    @Test
+    public void testIgmpQueryStatistics() throws InterruptedException {
+        igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
+        igmpManager.activate();
+
+        flagForQueryPacket = true;
+        //IGMPV3 Group Specific Membership Query packet
+        Ethernet igmpv3MembershipQueryPkt = IgmpSender.getInstance().buildIgmpV3Query(GROUP_IP, SOURCE_IP_OF_A);
+        sendPacket(igmpv3MembershipQueryPkt);
+
+        //IGMPV3 General Membership Query packet
+        Ethernet igmpv3MembershipQueryPkt1 =
+              IgmpSender.getInstance().buildIgmpV3Query(Ip4Address.valueOf(0), SOURCE_IP_OF_A);
+        sendPacket(igmpv3MembershipQueryPkt1);
+        assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
+        assertEquals(igmpStatisticsManager.getIgmpStats()
+            .getIgmpGrpAndSrcSpecificMembershipQuery().longValue(), 1));
+        assertEquals(igmpStatisticsManager.getIgmpStats()
+            .getIgmpGeneralMembershipQuery().longValue(), 1);
+        assertEquals(igmpStatisticsManager.getIgmpStats()
+             .getCurrentGrpNumCounter().longValue(), 1);
+    }
+
+    //Test Events
+    @Test
+    public void testIgmpStatisticsEvent() {
+        final int waitEventGeneration = igmpStatisticsManager.statisticsGenerationPeriodInSeconds * 1000;
+        //assert that event listened as the app activates
+        assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
+            assertEquals(mockListener.events.size(), 1));
+
+        assertAfter(waitEventGeneration / 2, waitEventGeneration, () ->
+            assertEquals(mockListener.events.size(), 2));
+
+        for (IgmpStatisticsEvent event : mockListener.events) {
+            assertEquals(event.type(), IgmpStatisticsEvent.Type.STATS_UPDATE);
+        }
+    }
+
+    //Test packet with Unknown Wrong Membership mode
+    @Test
+    public void testWrongIgmpPacket() throws InterruptedException {
+        SingleStateMachine.sendQuery = false;
+
+        igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
+        igmpManager.activate();
+
+        Ethernet firstPacket = buildWrongIgmpPacket(GROUP_IP, SOURCE_IP_OF_A);
+        // Sending first packet
+        sendPacket(firstPacket);
+        assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
+        assertEquals((long) 1,
+            igmpStatisticsManager.getIgmpStats().getReportsRxWithWrongModeCounter().longValue()));
+    }
+
+    //Test packet with Unknown IGMP type.
+    @Test
+    public void testUnknownIgmpPacket() throws InterruptedException {
+        SingleStateMachine.sendQuery = false;
+
+        igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
+        igmpManager.activate();
+
+        Ethernet firstPacket = buildUnknownIgmpPacket(GROUP_IP, SOURCE_IP_OF_A);
+        // Sending first packet
+        sendPacket(firstPacket);
+        assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
+        assertEquals((long) 1,
+            igmpStatisticsManager.getIgmpStats().getUnknownIgmpTypePacketsRxCounter().longValue()));
+    }
+
+    //Test packet with Insufficient Permission.
+    @Test
+    public void testSufficientPermission() throws InterruptedException {
+        SingleStateMachine.sendQuery = false;
+
+        flagForPermission = true;
+        igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
+        igmpManager.activate();
+
+        Ethernet firstPacket = IgmpSender.getInstance().buildIgmpV3Join(GROUP_IP, SOURCE_IP_OF_A);
+        // Sending first packet
+        sendPacket(firstPacket);
+        assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
+        assertEquals((long) 1,
+            igmpStatisticsManager.getIgmpStats().getFailJoinReqInsuffPermissionAccessCounter().longValue()));
+    }
+
+    public class MockIgmpStatisticsEventListener implements IgmpStatisticsEventListener {
+        protected List<IgmpStatisticsEvent> events = Lists.newArrayList();
+
+        @Override
+        public void event(IgmpStatisticsEvent event) {
+            events.add(event);
+        }
+
+    }
+}
