diff --git a/app/src/test/java/org/opencord/aaa/impl/AaaIntegrationTest.java b/app/src/test/java/org/opencord/aaa/impl/AaaIntegrationTest.java
new file mode 100644
index 0000000..8ded2f8
--- /dev/null
+++ b/app/src/test/java/org/opencord/aaa/impl/AaaIntegrationTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onlab.packet.EAP;
+import org.onlab.packet.EAPOL;
+import org.onlab.packet.Ethernet;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.opencord.aaa.AaaConfig;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Set of tests of the ONOS application component. These use an existing RADIUS
+ * server and sends live packets over the network to it.
+ */
+@Ignore ("This should not be run as part of the standard build")
+public class AaaIntegrationTest extends AaaTestBase {
+
+    private AaaManager aaa;
+
+    /**
+     * Mocks the network config registry.
+     */
+    @SuppressWarnings("unchecked")
+    static final class TestNetworkConfigRegistry
+            extends NetworkConfigRegistryAdapter {
+        @Override
+        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+            return (C) new AaaConfig();
+        }
+    }
+
+    /**
+     * Sets up the services required by the AAA application.
+     */
+    @Before
+    public void setUp() {
+        aaa = new AaaManager();
+        aaa.netCfgService = new TestNetworkConfigRegistry();
+        aaa.coreService = new CoreServiceAdapter();
+        aaa.packetService = new MockPacketService();
+        aaa.activate();
+    }
+
+    /**
+     * 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 Ethernet fetchPacket(int index) {
+        for (int iteration = 0; iteration < 20; iteration++) {
+            if (savedPackets.size() > index) {
+                return (Ethernet) savedPackets.get(index);
+            } else {
+                try {
+                    Thread.sleep(250);
+                } catch (Exception ex) {
+                    return null;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Tests the authentication path through the AAA application by sending
+     * packets to the RADIUS server and checking the state machine
+     * transitions.
+     *
+     * @throws Exception when an unhandled error occurs
+     */
+    @Test
+    public void testAuthentication()  throws Exception {
+
+        //  (1) Supplicant start up
+
+        Ethernet startPacket = constructSupplicantStartPacket();
+        sendPacket(startPacket);
+
+        Ethernet responsePacket = fetchPacket(0);
+        assertThat(responsePacket, notNullValue());
+        checkRadiusPacket(aaa, responsePacket, EAP.REQUEST);
+
+        //  (2) Supplicant identify
+
+        Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
+        sendPacket(identifyPacket);
+
+        //  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
+
+        Ethernet radiusChallengeMD5Packet = fetchPacket(1);
+        assertThat(radiusChallengeMD5Packet, notNullValue());
+        checkRadiusPacket(aaa, radiusChallengeMD5Packet, EAP.REQUEST);
+
+
+        // (4) Supplicant MD5 response
+
+        Ethernet md5RadiusPacket =
+                constructSupplicantIdentifyPacket(stateMachine,
+                                                  EAP.ATTR_MD5,
+                                                  stateMachine.challengeIdentifier(),
+                                                  radiusChallengeMD5Packet);
+        sendPacket(md5RadiusPacket);
+
+
+        // (5) RADIUS Success
+
+        Ethernet successRadiusPacket = fetchPacket(2);
+        assertThat(successRadiusPacket, notNullValue());
+        EAPOL successEapol = (EAPOL) successRadiusPacket.getPayload();
+        EAP successEap = (EAP) successEapol.getPayload();
+        assertThat(successEap.getCode(), is(EAP.SUCCESS));
+
+        //  State machine should be in authorized state
+
+        assertThat(stateMachine, notNullValue());
+        assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
+
+    }
+
+}
+
diff --git a/app/src/test/java/org/opencord/aaa/impl/AaaManagerTest.java b/app/src/test/java/org/opencord/aaa/impl/AaaManagerTest.java
new file mode 100644
index 0000000..8827c1a
--- /dev/null
+++ b/app/src/test/java/org/opencord/aaa/impl/AaaManagerTest.java
@@ -0,0 +1,305 @@
+/*
+ * 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.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.InboundPacket;
+import org.opencord.aaa.AaaConfig;
+
+import java.lang.reflect.Field;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+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;
+
+/**
+ * Set of tests of the ONOS application component.
+ */
+public class AaaManagerTest extends AaaTestBase {
+
+    static final String BAD_IP_ADDRESS = "198.51.100.0";
+
+    private AaaManager aaaManager;
+
+    class AaaManagerWithoutRadiusServer extends AaaManager {
+        protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
+            savePacket(radiusPacket);
+        }
+    }
+
+    /**
+     * 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) {
+                // can't happen
+                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());
+
+        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;
+            }
+        }
+    }
+
+    /**
+     * Sets 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();
+        TestUtils.setField(aaaManager, "eventDispatcher", new TestEventDispatcher());
+        aaaManager.activate();
+    }
+
+    /**
+     * Tears down the AAA application.
+     */
+    @After
+    public void tearDown() {
+        aaaManager.deactivate();
+    }
+
+    /**
+     * 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.
+     *
+     * @throws DeserializationException if packed deserialization fails.
+     */
+    @Test
+    public void testAuthentication()  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));
+
+    }
+
+    /**
+     * Tests the default configuration.
+     */
+    @Test
+    public void testConfig() {
+        assertThat(aaaManager.nasIpAddress.getHostAddress(), is(AaaConfig.DEFAULT_NAS_IP));
+        assertThat(aaaManager.nasMacAddress, is(AaaConfig.DEFAULT_NAS_MAC));
+        assertThat(aaaManager.radiusIpAddress.getHostAddress(), is(BAD_IP_ADDRESS));
+        assertThat(aaaManager.radiusMacAddress, is(AaaConfig.DEFAULT_RADIUS_MAC));
+    }
+}
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));
+    }
+}
diff --git a/app/src/test/java/org/opencord/aaa/impl/StateMachineTest.java b/app/src/test/java/org/opencord/aaa/impl/StateMachineTest.java
new file mode 100644
index 0000000..4053ff9
--- /dev/null
+++ b/app/src/test/java/org/opencord/aaa/impl/StateMachineTest.java
@@ -0,0 +1,300 @@
+/*
+ * 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.aaa.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.MacAddress;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class StateMachineTest {
+    StateMachine stateMachine = null;
+
+    @Before
+    public void setUp() {
+        System.out.println("Set Up.");
+        StateMachine.initializeMaps();
+        StateMachine.setDelegate(e -> { });
+        stateMachine = new StateMachine("session0");
+    }
+
+    @After
+    public void tearDown() {
+        System.out.println("Tear Down.");
+        StateMachine.destroyMaps();
+        stateMachine = null;
+    }
+
+    @Test
+    /**
+     * Test all the basic inputs from state to state: IDLE -> STARTED -> PENDING -> AUTHORIZED -> IDLE
+     */
+    public void basic() throws StateMachineException {
+        System.out.println("======= BASIC =======.");
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+    }
+
+    @Test
+    /**
+     * Test all inputs from an IDLE state (starting with the ones that are not impacting the current state)
+     */
+    public void testIdleState() throws StateMachineException {
+        System.out.println("======= IDLE STATE TEST =======.");
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+    }
+
+    @Test
+    /**
+     * Test all inputs from an STARTED state (starting with the ones that are not impacting the current state)
+     */
+    public void testStartedState() throws StateMachineException {
+        System.out.println("======= STARTED STATE TEST =======.");
+        stateMachine.start();
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+    }
+
+    @Test
+    /**
+     * Test all inputs from a PENDING state (starting with the ones that are not impacting the current state).
+     * The next valid state for this test is AUTHORIZED
+     */
+    public void testPendingStateToAuthorized() throws StateMachineException {
+        System.out.println("======= PENDING STATE TEST (AUTHORIZED) =======.");
+        stateMachine.start();
+        stateMachine.requestAccess();
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+    }
+
+    @Test
+    /**
+     * Test all inputs from an PENDING state (starting with the ones that are not impacting the current state).
+     * The next valid state for this test is UNAUTHORIZED
+     */
+    public void testPendingStateToUnauthorized() throws StateMachineException {
+        System.out.println("======= PENDING STATE TEST (DENIED) =======.");
+        stateMachine.start();
+        stateMachine.requestAccess();
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED);
+    }
+
+    @Test
+    /**
+     * Test all inputs from an AUTHORIZED state (starting with the ones that are not impacting the current state).
+     */
+    public void testAuthorizedState() throws StateMachineException {
+        System.out.println("======= AUTHORIZED STATE TEST =======.");
+        stateMachine.start();
+        stateMachine.requestAccess();
+        stateMachine.authorizeAccess();
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+    }
+
+    @Test
+    /**
+     * Test all inputs from an UNAUTHORIZED state (starting with the ones that are not impacting the current state).
+     */
+    public void testUnauthorizedState() throws StateMachineException {
+        System.out.println("======= UNAUTHORIZED STATE TEST =======.");
+        stateMachine.start();
+        stateMachine.requestAccess();
+        stateMachine.denyAccess();
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+    }
+
+    @Test
+    public void testSessionIdLookups() {
+        String sessionId1 = "session1";
+        String sessionId2 = "session2";
+        String sessionId3 = "session3";
+
+        StateMachine machine1ShouldBeNull =
+                StateMachine.lookupStateMachineBySessionId(sessionId1);
+        assertNull(machine1ShouldBeNull);
+        StateMachine machine2ShouldBeNull =
+                StateMachine.lookupStateMachineBySessionId(sessionId2);
+        assertNull(machine2ShouldBeNull);
+
+        StateMachine stateMachine1 = new StateMachine(sessionId1);
+        StateMachine stateMachine2 = new StateMachine(sessionId2);
+
+        assertEquals(stateMachine1,
+                     StateMachine.lookupStateMachineBySessionId(sessionId1));
+        assertEquals(stateMachine2,
+                     StateMachine.lookupStateMachineBySessionId(sessionId2));
+        assertNull(StateMachine.lookupStateMachineBySessionId(sessionId3));
+    }
+
+    @Test
+    public void testIdentifierLookups() throws StateMachineException {
+        String sessionId1 = "session1";
+        String sessionId2 = "session2";
+
+        StateMachine machine1ShouldBeNull =
+                StateMachine.lookupStateMachineById((byte) 1);
+        assertNull(machine1ShouldBeNull);
+        StateMachine machine2ShouldBeNull =
+                StateMachine.lookupStateMachineById((byte) 2);
+        assertNull(machine2ShouldBeNull);
+
+        StateMachine stateMachine1 = new StateMachine(sessionId1);
+        stateMachine1.start();
+        StateMachine stateMachine2 = new StateMachine(sessionId2);
+        stateMachine2.start();
+
+        assertEquals(stateMachine1,
+                     StateMachine.lookupStateMachineById(stateMachine1.identifier()));
+        assertEquals(stateMachine2,
+                     StateMachine.lookupStateMachineById(stateMachine2.identifier()));
+    }
+
+    @Test
+    /**
+     * Test state machine deletes
+     */
+    public void testStateMachineReset() throws StateMachineException {
+
+        int count = 256;
+
+        //StateMachine.initializeMaps();
+        StateMachine.lookupStateMachineById((byte) 1);
+
+        // Instantiate a bunch of state machines
+        for (int i = 0; i < count; i += 1) {
+            String mac = String.format("00:00:00:00:00:%02x", i);
+            StateMachine sm = new StateMachine(mac);
+            sm.start();
+            sm.setSupplicantAddress(MacAddress.valueOf(mac));
+        }
+
+        // Verify all state machines with a "even" MAC exist
+        for (int i = 0; i < count; i += 2) {
+            String mac = String.format("00:00:00:00:00:%02x", i);
+            assertNotNull(StateMachine.lookupStateMachineBySessionId(mac));
+        }
+
+        // Delete all state machines with a "even" MAC
+        for (int i = 0; i < count; i += 2) {
+            String mac = String.format("00:00:00:00:00:%02x", i);
+            StateMachine.deleteByMac(MacAddress.valueOf(mac));
+        }
+
+        // Verify all the delete state machines no long exist
+        for (int i = 0; i < count; i += 2) {
+            String mac = String.format("00:00:00:00:00:%02x", i);
+            assertNull(StateMachine.lookupStateMachineBySessionId(mac));
+        }
+    }
+}
