diff --git a/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java b/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java
new file mode 100644
index 0000000..2e21ea3
--- /dev/null
+++ b/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java
@@ -0,0 +1,334 @@
+/*
+ * 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 org.onlab.packet.BasePacket;
+import org.onlab.packet.EAP;
+import org.onlab.packet.EAPOL;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+
+import org.onosproject.net.Annotations;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Element;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+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 java.nio.ByteBuffer;
+import java.security.MessageDigest;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.onosproject.net.NetTestTools.connectPoint;
+
+/**
+ * Common methods for AAA app testing.
+ */
+public class AaaTestBase {
+
+    MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
+    MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a");
+
+    // Our session id will be the device ID ("of:1") with the port ("1") concatenated
+    static final String SESSION_ID = "of:11";
+
+    List<BasePacket> savedPackets = new LinkedList<>();
+    PacketProcessor packetProcessor;
+
+    /**
+     * Saves the given packet onto the saved packets list.
+     *
+     * @param packet packet to save
+     */
+    void savePacket(BasePacket packet) {
+        savedPackets.add(packet);
+    }
+
+    /**
+     * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
+     */
+    class MockPacketService extends PacketServiceAdapter {
+
+        @Override
+        public void addProcessor(PacketProcessor processor, int priority) {
+            packetProcessor = processor;
+        }
+
+        @Override
+        public void emit(OutboundPacket packet) {
+            try {
+                Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
+                                                                   0, packet.data().array().length);
+                savePacket(eth);
+            } catch (Exception e) {
+                fail(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Mocks the DeviceService.
+     */
+    final class TestDeviceService extends DeviceServiceAdapter {
+        @Override
+        public Port getPort(ConnectPoint cp) {
+            return new MockPort();
+        }
+    }
+    private class  MockPort implements Port {
+
+        @Override
+        public boolean isEnabled() {
+            return true;
+        }
+        public long portSpeed() {
+            return 1000;
+        }
+        public Element element() {
+            return null;
+        }
+        public PortNumber number() {
+            return null;
+        }
+        public Annotations annotations() {
+            return new MockAnnotations();
+        }
+        public Type type() {
+            return Port.Type.FIBER;
+        }
+
+        private class MockAnnotations implements Annotations {
+
+            @Override
+            public String value(String val) {
+                return "PON 1/1";
+            }
+            public Set<String> keys() {
+                return null;
+            }
+        }
+    }
+
+    private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
+
+        MockSubscriberAndDeviceInformation(String id, VlanId ctag,
+                                           VlanId stag, String nasPortId,
+                                           String circuitId, MacAddress hardId,
+                                           Ip4Address ipAddress) {
+            this.setCTag(ctag);
+            this.setHardwareIdentifier(hardId);
+            this.setId(id);
+            this.setIPAddress(ipAddress);
+            this.setSTag(stag);
+            this.setNasPortId(nasPortId);
+            this.setCircuitId(circuitId);
+        }
+    }
+
+    final class MockSadisService implements SadisService {
+
+        @Override
+        public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
+            return new MockSubService();
+        }
+
+        @Override
+        public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
+            return null;
+        }
+    }
+
+    final class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
+        private final VlanId clientCtag = VlanId.vlanId((short) 999);
+        private final VlanId clientStag = VlanId.vlanId((short) 111);
+        private final String clientNasPortId = "PON 1/1";
+        private final String clientCircuitId = "CIR-PON 1/1";
+
+        MockSubscriberAndDeviceInformation sub =
+                new MockSubscriberAndDeviceInformation(clientNasPortId, clientCtag,
+                        clientStag, clientNasPortId, clientCircuitId, null, null);
+        @Override
+        public SubscriberAndDeviceInformation get(String id) {
+
+                return  sub;
+
+        }
+
+        @Override
+        public void invalidateAll() {}
+        public void invalidateId(String id) {}
+        public SubscriberAndDeviceInformation getfromCache(String id) {
+            return null;
+        }
+    }
+    /**
+     * Mocks the DefaultPacketContext.
+     */
+    final class TestPacketContext extends DefaultPacketContext {
+
+        private 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 an Ethernet packet to the process method of the Packet Processor.
+     *
+     * @param reply Ethernet packet
+     */
+    void sendPacket(Ethernet reply) {
+        final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
+        InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
+                                                          reply,
+                                                          byteBuffer);
+
+        PacketContext context = new TestPacketContext(127L, inPacket, null, false);
+        packetProcessor.process(context);
+    }
+
+    /**
+     * Constructs an Ethernet packet containing identification payload.
+     *
+     * @return Ethernet packet
+     */
+    Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine,
+                                                       byte type,
+                                                       byte id,
+                                                       Ethernet radiusChallenge)
+            throws Exception {
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(clientMac.toBytes());
+        eth.setSourceMACAddress(serverMac.toBytes());
+        eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
+        eth.setVlanID((short) 2);
+
+        String username = "testuser";
+        byte[] data = username.getBytes();
+
+
+        if (type == EAP.ATTR_MD5) {
+            String password = "testpassword";
+            EAPOL eapol = (EAPOL) radiusChallenge.getPayload();
+            EAP eap = (EAP) eapol.getPayload();
+
+            byte[] identifier = new byte[password.length() + eap.getData().length];
+
+            identifier[0] = stateMachine.challengeIdentifier();
+            System.arraycopy(password.getBytes(), 0, identifier, 1, password.length());
+            System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16);
+
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] hash = md.digest(identifier);
+            data = new byte[17];
+            data[0] = (byte) 16;
+            System.arraycopy(hash, 0, data, 1, 16);
+        }
+        EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type,
+                          data);
+        eap.setIdentifier(id);
+
+        // eapol header
+        EAPOL eapol = new EAPOL();
+        eapol.setEapolType(EAPOL.EAPOL_PACKET);
+        eapol.setPacketLength(eap.getLength());
+
+        // eap part
+        eapol.setPayload(eap);
+
+        eth.setPayload(eapol);
+        eth.setPad(true);
+        return eth;
+    }
+
+    /**
+     * Constructs an Ethernet packet containing a EAPOL_START Payload.
+     *
+     * @return Ethernet packet
+     */
+    Ethernet constructSupplicantStartPacket() {
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(clientMac.toBytes());
+        eth.setSourceMACAddress(serverMac.toBytes());
+        eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
+        eth.setVlanID((short) 2);
+
+        EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 2, EAPOL.EAPOL_START, null);
+
+        // eapol header
+        EAPOL eapol = new EAPOL();
+        eapol.setEapolType(EAPOL.EAPOL_START);
+        eapol.setPacketLength(eap.getLength());
+
+        // eap part
+        eapol.setPayload(eap);
+
+        eth.setPayload(eapol);
+        eth.setPad(true);
+        return eth;
+    }
+
+    /**
+     * Checks the contents of a RADIUS packet being sent to the RADIUS server.
+     *
+     * @param radiusPacket packet to check
+     * @param code expected code
+     */
+    void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) {
+
+        assertThat(radiusPacket.getSourceMAC(),
+                   is(MacAddress.valueOf(aaaManager.nasMacAddress)));
+        assertThat(radiusPacket.getDestinationMAC(), is(serverMac));
+
+        assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class));
+        EAPOL eapol = (EAPOL) radiusPacket.getPayload();
+        assertThat(eapol, notNullValue());
+
+        assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET));
+        assertThat(eapol.getPayload(), instanceOf(EAP.class));
+        EAP eap = (EAP) eapol.getPayload();
+        assertThat(eap, notNullValue());
+
+        assertThat(eap.getCode(), is(code));
+    }
+}
