diff --git a/app/src/test/java/org/opencord/dhcpl2relay/impl/DhcpL2RelayTestBase.java b/app/src/test/java/org/opencord/dhcpl2relay/impl/DhcpL2RelayTestBase.java
new file mode 100755
index 0000000..5318adc
--- /dev/null
+++ b/app/src/test/java/org/opencord/dhcpl2relay/impl/DhcpL2RelayTestBase.java
@@ -0,0 +1,311 @@
+/*
+ * 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.dhcpl2relay.impl;
+
+import static org.junit.Assert.fail;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.DHCP;
+import org.onlab.packet.DHCPPacketType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.UDP;
+import org.onlab.packet.dhcp.DhcpOption;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.ConnectPoint;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Common methods for AAA app testing.
+ */
+public class DhcpL2RelayTestBase {
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final int TRANSACTION_ID = 1000;
+
+    private static final String EXPECTED_IP = "10.2.0.2";
+
+    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);
+    }
+
+    BasePacket getPacket() {
+        return savedPackets.remove(0);
+    }
+
+    /**
+     * Mock core service adaptor that provides an appId.
+     */
+    class MockCoreServiceAdapter extends CoreServiceAdapter {
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return new DefaultApplicationId(10, name);
+        }
+    }
+
+    /**
+     * 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 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 pkt Ethernet packet
+     */
+    void sendPacket(Ethernet pkt, ConnectPoint cp) {
+        final ByteBuffer byteBuffer = ByteBuffer.wrap(pkt.serialize());
+        InboundPacket inPacket = new DefaultInboundPacket(cp, pkt, byteBuffer);
+
+        PacketContext context = new TestPacketContext(127L, inPacket, null, false);
+        packetProcessor.process(context);
+    }
+
+    /**
+     * Constructs an Ethernet packet with IP/UDP/DHCP payload.
+     *
+     * @return Ethernet packet
+     */
+    private Ethernet construcEthernetPacket(MacAddress srcMac, MacAddress dstMac,
+                                                String dstIp, byte dhcpReqRsp,
+                                                MacAddress clientHwAddress,
+                                                Ip4Address dhcpClientIpAddress) {
+        // Ethernet Frame.
+        Ethernet ethPkt = new Ethernet();
+        ethPkt.setSourceMACAddress(srcMac);
+        ethPkt.setDestinationMACAddress(dstMac);
+        ethPkt.setEtherType(Ethernet.TYPE_IPV4);
+        ethPkt.setVlanID((short) 2);
+        ethPkt.setPriorityCode((byte) 6);
+
+        // IP Packet
+        IPv4 ipv4Reply = new IPv4();
+        ipv4Reply.setSourceAddress(0);
+        ipv4Reply.setDestinationAddress(dstIp);
+
+        ipv4Reply.setTtl((byte) 127);
+
+        // UDP Datagram.
+        UDP udpReply = new UDP();
+        udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
+        udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);
+
+        // DHCP Payload.
+        DHCP dhcpReply = new DHCP();
+        dhcpReply.setOpCode(dhcpReqRsp);
+
+        dhcpReply.setYourIPAddress(dhcpClientIpAddress.toInt());
+        dhcpReply.setServerIPAddress(0);
+
+        final byte[] serverNameBytes = new byte[64];
+        String result = new String(serverNameBytes, StandardCharsets.US_ASCII).trim();
+        dhcpReply.setServerName(result);
+
+        final byte[] bootFileBytes = new byte[128];
+        String result1 = new String(bootFileBytes, StandardCharsets.US_ASCII).trim();
+        dhcpReply.setBootFileName(result1);
+
+        dhcpReply.setTransactionId(TRANSACTION_ID);
+        dhcpReply.setClientHardwareAddress(clientHwAddress.toBytes());
+        dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
+        dhcpReply.setHardwareAddressLength((byte) 6);
+
+        udpReply.setPayload(dhcpReply);
+        ipv4Reply.setPayload(udpReply);
+        ethPkt.setPayload(ipv4Reply);
+
+        return ethPkt;
+    }
+
+    /**
+     * Constructs DHCP Discover Packet.
+     *
+     * @return Ethernet packet
+     */
+    Ethernet constructDhcpDiscoverPacket(MacAddress clientMac) {
+
+        Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
+                "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
+                Ip4Address.valueOf("0.0.0.0"));
+
+        IPv4 ipv4Packet = (IPv4) pkt.getPayload();
+        UDP udpPacket = (UDP) ipv4Packet.getPayload();
+        DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
+
+        dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPDISCOVER));
+
+        return pkt;
+    }
+
+    /**
+     * Constructs DHCP Request Packet.
+     *
+     * @return Ethernet packet
+     */
+    Ethernet constructDhcpRequestPacket(MacAddress clientMac) {
+
+        Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
+                "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
+                Ip4Address.valueOf("0.0.0.0"));
+
+        IPv4 ipv4Packet = (IPv4) pkt.getPayload();
+        UDP udpPacket = (UDP) ipv4Packet.getPayload();
+        DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
+
+        dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPREQUEST));
+
+        return pkt;
+    }
+
+    /**
+     * Constructs DHCP Offer Packet.
+     *
+     * @return Ethernet packet
+     */
+    Ethernet constructDhcpOfferPacket(MacAddress servMac, MacAddress clientMac,
+                                           String ipAddress, String dhcpClientIpAddress) {
+
+        Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
+                clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
+
+        IPv4 ipv4Packet = (IPv4) pkt.getPayload();
+        UDP udpPacket = (UDP) ipv4Packet.getPayload();
+        DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
+
+        dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPOFFER));
+
+        return pkt;
+    }
+
+    /**
+     * Constructs DHCP Ack Packet.
+     *
+     * @return Ethernet packet
+     */
+    Ethernet constructDhcpAckPacket(MacAddress servMac, MacAddress clientMac,
+                                           String ipAddress, String dhcpClientIpAddress) {
+
+        Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
+                clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
+
+        IPv4 ipv4Packet = (IPv4) pkt.getPayload();
+        UDP udpPacket = (UDP) ipv4Packet.getPayload();
+        DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
+
+        dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPACK));
+
+        return pkt;
+    }
+
+    /**
+     * Constructs DHCP Discover Options.
+     *
+     * @return Ethernet packet
+     */
+    private List<DhcpOption> constructDhcpOptions(DHCPPacketType packetType) {
+
+        // DHCP Options.
+        DhcpOption option = new DhcpOption();
+        List<DhcpOption> optionList = new ArrayList<>();
+
+
+        // DHCP Message Type.
+        option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
+        option.setLength((byte) 1);
+        byte[] optionData = {(byte) packetType.getValue()};
+        option.setData(optionData);
+        optionList.add(option);
+
+        // DHCP Requested IP.
+        option = new DhcpOption();
+        option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue());
+        option.setLength((byte) 4);
+        optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
+        option.setData(optionData);
+        optionList.add(option);
+
+        // End Option.
+        option = new DhcpOption();
+        option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
+        option.setLength((byte) 1);
+        optionList.add(option);
+
+        return optionList;
+    }
+}
