diff --git a/app/src/main/java/org/opencord/aaa/impl/AaaManager.java b/app/src/main/java/org/opencord/aaa/impl/AaaManager.java
index 040cf3e..55239a5 100755
--- a/app/src/main/java/org/opencord/aaa/impl/AaaManager.java
+++ b/app/src/main/java/org/opencord/aaa/impl/AaaManager.java
@@ -289,7 +289,7 @@
     statisticsGenerationEvent = Strings.isNullOrEmpty(s) ? DEFAULT_REPEAT_DELAY : Integer.parseInt(s.trim());
     }
 
-    private void configureRadiusCommunication() {
+    protected void configureRadiusCommunication() {
         if (radiusConnectionType.toLowerCase().equals("socket")) {
             impl = new SocketBasedRadiusCommunicator(appId, packetService, this);
         } else {
diff --git a/app/src/test/java/org/opencord/aaa/impl/AaaStatisticsTest.java b/app/src/test/java/org/opencord/aaa/impl/AaaStatisticsTest.java
new file mode 100644
index 0000000..e4718b7
--- /dev/null
+++ b/app/src/test/java/org/opencord/aaa/impl/AaaStatisticsTest.java
@@ -0,0 +1,458 @@
+/*
+ * Copyright 2015-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.aaa.impl;
+
+import com.google.common.base.Charsets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.EAP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.RADIUS;
+import org.onlab.packet.RADIUSAttribute;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.event.DefaultEventSinkRegistry;
+import org.onosproject.event.Event;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.event.EventSink;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketService;
+import org.opencord.aaa.AaaConfig;
+import org.slf4j.Logger;
+
+import java.lang.reflect.Field;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+
+import static com.google.common.base.Preconditions.checkState;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.onosproject.net.NetTestTools.connectPoint;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Set of tests of the ONOS application component for AAA Statistics.
+ */
+public class AaaStatisticsTest extends AaaTestBase {
+
+    static final String BAD_IP_ADDRESS = "198.51.100.0";
+
+    private final Logger log = getLogger(getClass());
+    private AaaManager aaaManager;
+    private AaaStatisticsManager aaaStatisticsManager;
+
+    class AaaManagerWithoutRadiusServer extends AaaManager {
+       protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
+          super.sendRadiusPacket(radiusPacket, inPkt);
+          aaaManager.aaaStatisticsManager.putOutgoingIdentifierToMap(radiusPacket.getIdentifier());
+          savePacket(radiusPacket);
+       }
+
+       // changed the configuration of parent method to protected
+       protected void configureRadiusCommunication() {
+           PacketService pktService = new MockPacketService();
+           ApplicationId appId = new CoreServiceAdapter().registerApplication("org.opencord.aaa");
+           aaaManager.impl = new TestSocketBasedRadiusCommunicator(appId, pktService, aaaManager);
+           }
+       }
+
+    /**
+     * Mocks the AAAConfig class to force usage of an unroutable address for the
+     * RADIUS server.
+     */
+    static class MockAaaConfig extends AaaConfig {
+        @Override
+        public InetAddress radiusIp() {
+          try {
+                return InetAddress.getByName(BAD_IP_ADDRESS);
+              } catch (UnknownHostException ex) {
+                throw new IllegalStateException(ex);
+               }
+        }
+       }
+
+    /**
+     * Mocks the network config registry.
+     */
+    @SuppressWarnings("unchecked")
+    private static final class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
+        @Override
+        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+            AaaConfig aaaConfig = new MockAaaConfig();
+            return (C) aaaConfig;
+         }
+    }
+
+    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;
+       }
+     }
+
+    /**
+     * Constructs an Ethernet packet containing a RADIUS challenge packet.
+     *
+     * @param challengeCode
+     * code to use in challenge packet
+     * @param challengeType
+     *            type to use in challenge packet
+     * @return Ethernet packet
+     */
+   private RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType) {
+
+     String challenge = "12345678901234567";
+     EAP eap = new EAP(challengeType, (byte) 1, challengeType, challenge.getBytes(Charsets.US_ASCII));
+     eap.setIdentifier((byte) 1);
+
+     RADIUS radius = new RADIUS();
+     radius.setCode(challengeCode);
+
+     radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE, challenge.getBytes(Charsets.US_ASCII));
+
+     radius.setPayload(eap);
+     radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE, eap.serialize());
+     radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, aaaManager.radiusSecret.getBytes());
+     return radius;
+
+   }
+
+    public static void injectEventDispatcher(Object manager, EventDeliveryService svc) {
+       Class mc = manager.getClass();
+       for (Field f : mc.getSuperclass().getDeclaredFields()) {
+          if (f.getType().equals(EventDeliveryService.class)) {
+           try {
+                 TestUtils.setField(manager, f.getName(), svc);
+               } catch (TestUtils.TestUtilsException e) {
+                    throw new IllegalArgumentException("Unable to inject reference", e);
+               }
+                break;
+          }
+      }
+    }
+
+/**
+ * Set up the services required by the AAA application.
+ */
+    @Before
+    public void setUp() {
+        aaaManager = new AaaManagerWithoutRadiusServer();
+        aaaManager.netCfgService = new TestNetworkConfigRegistry();
+        aaaManager.coreService = new CoreServiceAdapter();
+        aaaManager.packetService = new MockPacketService();
+        aaaManager.deviceService = new TestDeviceService();
+        aaaManager.sadisService = new MockSadisService();
+        aaaManager.cfgService = new MockCfgService();
+        aaaStatisticsManager = new AaaStatisticsManager();
+        TestUtils.setField(aaaStatisticsManager, "eventDispatcher", new TestEventDispatcher());
+        aaaStatisticsManager.activate();
+        aaaManager.aaaStatisticsManager = this.aaaStatisticsManager;
+        TestUtils.setField(aaaManager, "eventDispatcher", new TestEventDispatcher());
+        aaaManager.activate(new AaaTestBase.MockComponentContext());
+    }
+
+/**
+ * Tear down the AAA application.
+ */
+@After
+public void tearDown() {
+  aaaManager.deactivate(new AaaTestBase.MockComponentContext());
+}
+
+/**
+ * Extracts the RADIUS packet from a packet sent by the supplicant.
+ *
+ * @param radius
+ *            RADIUS packet sent by the supplicant
+ * @throws DeserializationException
+ *             if deserialization of the packet contents fails.
+ */
+private void checkRadiusPacketFromSupplicant(RADIUS radius) throws DeserializationException {
+   assertThat(radius, notNullValue());
+   EAP eap = radius.decapsulateMessage();
+   assertThat(eap, notNullValue());
+}
+
+/**
+ * Fetches the sent packet at the given index. The requested packet must be the
+ * last packet on the list.
+ *
+ * @param index
+ *            index into sent packets array
+ * @return packet
+ */
+private BasePacket fetchPacket(int index) {
+    BasePacket packet = savedPackets.get(index);
+    assertThat(packet, notNullValue());
+    return packet;
+}
+
+    /** Tests the authentication path through the AAA application.
+     *  And counts the aaa Stats for successful transmission.
+     *   @throws DeserializationException
+     *  if packed deserialization fails.
+     */
+    @Test
+    public void testAaaStatisticsForAcceptedPackets() throws Exception {
+
+        // (1) Supplicant start up
+        Ethernet startPacket = constructSupplicantStartPacket();
+        sendPacket(startPacket);
+
+        Ethernet responsePacket = (Ethernet) fetchPacket(0);
+        checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
+
+        // (2) Supplicant identify
+
+        Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
+        sendPacket(identifyPacket);
+
+        RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
+        checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
+
+        assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
+        assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
+                is("testuser"));
+        IpAddress nasIp = IpAddress.valueOf(IpAddress.Version.INET,
+                  radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP).getValue());
+        assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress()));
+
+        // State machine should have been created by now
+
+        StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(SESSION_ID);
+        assertThat(stateMachine, notNullValue());
+        assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
+
+        // (3) RADIUS MD5 challenge
+
+       RADIUS radiusCodeAccessChallengePacket = constructRadiusCodeAccessChallengePacket(
+                  RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
+        aaaManager.handleRadiusPacket(radiusCodeAccessChallengePacket);
+
+        Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
+        checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5);
+
+        // (4) Supplicant MD5 response
+
+       Ethernet md5RadiusPacket = constructSupplicantIdentifyPacket(stateMachine, EAP.ATTR_MD5,
+           stateMachine.challengeIdentifier(), radiusChallengeMD5Packet);
+       sendPacket(md5RadiusPacket);
+
+        RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3);
+
+        checkRadiusPacketFromSupplicant(responseMd5RadiusPacket);
+        assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 3));
+        assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
+
+        // State machine should be in pending state
+
+        assertThat(stateMachine, notNullValue());
+        assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
+
+        // (5) RADIUS Success
+
+        RADIUS successPacket =
+                constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS);
+        aaaManager.handleRadiusPacket((successPacket));
+        Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4);
+
+        checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS);
+
+        // State machine should be in authorized state
+
+        assertThat(stateMachine, notNullValue());
+        assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
+
+       // Counts the aaa Statistics count and displays in the log
+       countAaaStatistics();
+
+    }
+
+    /** Tests the count for defected packets.
+     *
+     *   @throws DeserializationException
+     * if packed deserialization fails.
+     */
+    @Test
+    public void testAaaStatisticsForDefectivePackets() throws Exception {
+        // (1) Supplicant start up
+        Ethernet startPacket = constructSupplicantStartPacket();
+        sendPacket(startPacket);
+
+        // (2) Supplicant identify
+
+        Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
+        sendPacket(identifyPacket);
+
+        RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
+
+        checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
+
+        // Calling the mock test socket based to handle packet
+        aaaManager.impl.handlePacketFromServer(null);
+        // State machine should have been created by now
+
+        StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(SESSION_ID);
+
+        // (3) RADIUS MD5 challenge
+
+        RADIUS radiusCodeAccessChallengePacket = constructRadiusCodeAccessChallengePacket(
+               RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
+        aaaManager.handleRadiusPacket(radiusCodeAccessChallengePacket);
+
+        Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
+
+        // (4) Supplicant MD5 response
+
+        Ethernet md5RadiusPacket = constructSupplicantIdentifyPacket(stateMachine, EAP.ATTR_MD5,
+              stateMachine.challengeIdentifier(), radiusChallengeMD5Packet);
+        sendPacket(md5RadiusPacket);
+        aaaManager.aaaStatisticsManager.calculatePacketRoundtripTime();
+        // (5) RADIUS Rejected
+
+        RADIUS rejectedPacket =
+               constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_REJECT, EAP.FAILURE);
+        aaaManager.handleRadiusPacket((rejectedPacket));
+        Ethernet supplicantRejectedPacket = (Ethernet) fetchPacket(4);
+
+        checkRadiusPacket(aaaManager, supplicantRejectedPacket, EAP.FAILURE);
+
+        // State machine should be in unauthorized state
+        assertThat(stateMachine, notNullValue());
+        assertThat(stateMachine.state(), is(StateMachine.STATE_UNAUTHORIZED));
+        // Calculated the total round trip time
+        aaaManager.aaaStatisticsManager.calculatePacketRoundtripTime();
+        // Counts the aaa Statistics count and displays in the log
+        countAaaStatistics();
+
+     }
+
+    /*
+     * Tests the retransmitted packet and malformed packet count
+     *
+     * @throws DeserializationException
+     *  if packed deserialization fails.
+     */
+    @Test
+    public void testRequestRetransmittedCount() throws Exception {
+
+        // (1) Supplicant start up
+        Ethernet startPacket = constructSupplicantStartPacket();
+        sendPacket(startPacket);
+
+        // (2) Supplicant identify
+
+        Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
+        sendPacket(identifyPacket);
+
+        RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
+        checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
+
+        // again creating pending state for same packet
+        constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
+        sendPacket(identifyPacket);
+        aaaManager.impl.handlePacketFromServer(null);
+        aaaManager.aaaStatisticsManager.calculatePacketRoundtripTime();
+
+        // creating malformed packet
+        final ByteBuffer byteBuffer = ByteBuffer.wrap(startPacket.serialize());
+        InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
+              startPacket, byteBuffer);
+
+        PacketContext context = new TestPacketContext(127L, inPacket, null, false);
+        aaaManager.impl.handlePacketFromServer(context);
+        countAaaStatistics();
+
+     }
+
+    // Calculates the AAA statistics count.
+    public void countAaaStatistics() {
+        assertThat(aaaStatisticsManager.getAaaStats().getAcceptResponsesRx(), notNullValue());
+        assertThat(aaaStatisticsManager.getAaaStats().getAccessRequestsTx(), notNullValue());
+        assertThat(aaaStatisticsManager.getAaaStats().getChallengeResponsesRx(), notNullValue());
+        assertThat(aaaStatisticsManager.getAaaStats().getDroppedResponsesRx(), notNullValue());
+        assertThat(aaaStatisticsManager.getAaaStats().getInvalidValidatorsRx(), notNullValue());
+        assertThat(aaaStatisticsManager.getAaaStats().getMalformedResponsesRx(), notNullValue());
+        assertThat(aaaStatisticsManager.getAaaStats().getPendingRequests(), notNullValue());
+        assertThat(aaaStatisticsManager.getAaaStats().getRejectResponsesRx(), notNullValue());
+        assertThat(aaaStatisticsManager.getAaaStats().getRequestReTx(), notNullValue());
+        assertThat(aaaStatisticsManager.getAaaStats().getRequestRttMilis(), notNullValue());
+        assertThat(aaaStatisticsManager.getAaaStats().getUnknownServerRx(), notNullValue());
+        assertThat(aaaStatisticsManager.getAaaStats().getUnknownTypeRx(), notNullValue());
+    }
+
+    /*
+     * Mock implementation of SocketBasedRadiusCommunicator class.
+     *
+     */
+    class TestSocketBasedRadiusCommunicator extends SocketBasedRadiusCommunicator {
+
+      TestSocketBasedRadiusCommunicator(ApplicationId appId, PacketService pktService, AaaManager aaaManager) {
+          super(appId, pktService, aaaManager);
+      }
+
+        // Implementation of socketBasedRadiusCommunicator--> run() method
+        public void handlePacketFromServer(PacketContext context) {
+
+           RADIUS incomingPkt = (RADIUS) fetchPacket(savedPackets.size() - 1);
+           try {
+                 if (context == null) {
+                    aaaStatisticsManager.handleRoundtripTime(incomingPkt.getIdentifier());
+                    aaaManager.handleRadiusPacket(incomingPkt);
+                } else if (null != context) {
+                    aaaManager.checkForPacketFromUnknownServer("100.100.100.0");
+                    aaaStatisticsManager.handleRoundtripTime(incomingPkt.getIdentifier());
+                    aaaManager.handleRadiusPacket(incomingPkt);
+                    incomingPkt =
+                            RADIUS.deserializer().deserialize(incomingPkt.generateAuthCode(), 0, 1);
+                }
+                } catch (DeserializationException dex) {
+                    aaaManager.aaaStatisticsManager.getAaaStats().increaseMalformedResponsesRx();
+                    aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
+                    log.error("Cannot deserialize packet", dex);
+                } catch (StateMachineException sme) {
+                    log.error("Illegal state machine operation", sme);
+        }
+
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java b/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java
index b49fbc4..4912e4e 100644
--- a/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java
+++ b/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java
@@ -319,7 +319,7 @@
      */
     final class TestPacketContext extends DefaultPacketContext {
 
-        private TestPacketContext(long time, InboundPacket inPkt,
+        TestPacketContext(long time, InboundPacket inPkt,
                                   OutboundPacket outPkt, boolean block) {
             super(time, inPkt, outPkt, block);
         }
