[ONOS-7731] Add test code implementation of openstack vtap app

Change-Id: I2e7125ed3d1ae23366ba71c7e3d40acf96f91e5a
diff --git a/apps/openstackvtap/app/BUILD b/apps/openstackvtap/app/BUILD
index f094c0b..3b3c6d7 100644
--- a/apps/openstackvtap/app/BUILD
+++ b/apps/openstackvtap/app/BUILD
@@ -16,6 +16,7 @@
     api_package = "org.onosproject.openstackvtap.web",
     api_title = "Openstack Vtap REST API",
     api_version = "1.0",
+    exclude_tests = ["org.onosproject.openstackvtap.impl.OpenstackVtapTest"],
     karaf_command_packages = ["org.onosproject.openstackvtap.cli"],
     test_deps = TEST_DEPS,
     web_context = "/onos/openstackvtap",
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapDeleteCommand.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapDeleteCommand.java
index 17db27c..26ae5d8 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapDeleteCommand.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapDeleteCommand.java
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 package org.onosproject.openstackvtap.cli;
+import org.apache.karaf.shell.api.action.Argument;
 import org.apache.karaf.shell.api.action.Command;
 import org.apache.karaf.shell.api.action.Completion;
 import org.apache.karaf.shell.api.action.lifecycle.Service;
 import org.onosproject.cli.AbstractShellCommand;
-import org.apache.karaf.shell.api.action.Argument;
 import org.onosproject.openstackvtap.api.OpenstackVtap;
 import org.onosproject.openstackvtap.api.OpenstackVtapAdminService;
 import org.onosproject.openstackvtap.api.OpenstackVtapId;
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/codec/OpenstackVtapNetworkCodec.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/codec/OpenstackVtapNetworkCodec.java
index 6dd6b5c..bd5a0d7 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/codec/OpenstackVtapNetworkCodec.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/codec/OpenstackVtapNetworkCodec.java
@@ -37,7 +37,6 @@
     private static final String MODE = "mode";
     private static final String NETWORK_ID = "networkId";
     private static final String SERVER_IP = "serverIp";
-    private static final String NODES = "nodes";
 
     private static final String JSON_NULL_MESSAGE = "% cannot be null";
     private static final String JSON_MISSING_MESSAGE = "% is required";
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtap.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtap.java
index cc258c0..1584a3a 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtap.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtap.java
@@ -165,7 +165,6 @@
             this.id = description.id();
             this.type = description.type();
             this.vtapCriterion = description.vtapCriterion();
-            this.type = description.type();
             this.txDeviceIds = description.txDeviceIds();
             this.rxDeviceIds = description.rxDeviceIds();
             this.annotations  = (SparseAnnotations) description.annotations();
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapNetwork.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapNetwork.java
index af086a2..3f7fdc5 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapNetwork.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapNetwork.java
@@ -29,7 +29,7 @@
 /**
  * Default implementation of an immutable OpenstackVtapNetwork.
  */
-public class DefaultOpenstackVtapNetwork extends AbstractDescription implements OpenstackVtapNetwork {
+public final class DefaultOpenstackVtapNetwork extends AbstractDescription implements OpenstackVtapNetwork {
 
     private final Mode mode;
     private final Integer networkId;
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/OpenstackVtapManager.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/OpenstackVtapManager.java
index 439b084..095080c 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/OpenstackVtapManager.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/OpenstackVtapManager.java
@@ -232,7 +232,7 @@
     private static final int INTERFACE_MANIPULATION_RETRY = 10;     // 10 times (totally 10sec)
 
     @Activate
-    public void activate(ComponentContext context) {
+    public void activate() {
         appId = coreService.registerApplication(APP_ID);
         localNodeId = clusterService.getLocalNode().id();
         leadershipService.runForLeadership(appId.name());
@@ -512,6 +512,10 @@
      * @return a collection of device identifiers
      */
     private Set<DeviceId> getEdgeDevice(Type type, OpenstackVtapCriterion criterion) {
+        if (hostService.getHosts() == null) {
+            return ImmutableSet.of();
+        }
+
         Set<DeviceId> deviceIds = Sets.newConcurrentHashSet();
         StreamSupport.stream(hostService.getHosts().spliterator(), true)
                 .filter(host -> isValidHost(host) &&
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/web/OpenstackVtapNetworkWebResource.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/web/OpenstackVtapNetworkWebResource.java
index 3900bbd..60fcc14 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/web/OpenstackVtapNetworkWebResource.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/web/OpenstackVtapNetworkWebResource.java
@@ -17,8 +17,8 @@
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.onosproject.openstackvtap.api.OpenstackVtapAdminService;
 import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
+import org.onosproject.openstackvtap.api.OpenstackVtapService;
 import org.onosproject.rest.AbstractWebResource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -55,15 +55,15 @@
 
     private static final String NETWORK = "network";
 
-    private final OpenstackVtapAdminService vtapAdminService = get(OpenstackVtapAdminService.class);
+    private final OpenstackVtapService vtapService = get(OpenstackVtapService.class);
 
     /**
      * Creates a openstack vtap network from the JSON input stream.
      *
      * @param input openstack vtap network JSON input stream
-     * @return 200 OK if the JSON is correct
+     * @return 200 OK on creating success
      *         400 BAD_REQUEST if the JSON is malformed
-     *         409 CONFLICT if already the vtap network exists
+     *         409 CONFLICT if already the openstack vtap network exists
      * @onos.rsModel OpenstackVtapNetwork
      */
     @POST
@@ -76,7 +76,7 @@
             return Response.status(Response.Status.BAD_REQUEST).build();
         }
 
-        if (vtapAdminService.createVtapNetwork(vtapNetwork.mode(),
+        if (vtapService.createVtapNetwork(vtapNetwork.mode(),
                 vtapNetwork.networkId(), vtapNetwork.serverIp()) == null) {
             log.warn(ERROR_DUPLICATE, vtapNetwork);
             return Response.status(Response.Status.CONFLICT).build();
@@ -88,9 +88,9 @@
      * Updates openstack vtap network from the JSON input stream.
      *
      * @param input openstack vtap network JSON input stream
-     * @return 200 OK if the JSON is correct
+     * @return 200 OK on updating success
      *         400 BAD_REQUEST if the JSON is malformed
-     *         404 NOT_FOUND if vtap network is not exists
+     *         404 NOT_FOUND if openstack vtap network is not exists
      * @onos.rsModel OpenstackVtapNetwork
      */
     @PUT
@@ -103,7 +103,7 @@
             return Response.status(Response.Status.BAD_REQUEST).build();
         }
 
-        if (vtapAdminService.updateVtapNetwork(vtapNetwork) == null) {
+        if (vtapService.updateVtapNetwork(vtapNetwork) == null) {
             log.warn(ERROR_NOTFOUND, vtapNetwork);
             return Response.status(Response.Status.NOT_FOUND).build();
         }
@@ -111,10 +111,29 @@
     }
 
     /**
+     * Removes openstack network.
+     *
+     * @return 200 OK on removing success
+     *         404 NOT_FOUND if openstack vtap network is not exists
+     * @onos.rsModel OpenstackVtapNetwork
+     */
+    @DELETE
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response deleteNetwork() {
+        log.info(MESSAGE_NETWORK, DELETE);
+
+        if (vtapService.removeVtapNetwork() == null) {
+            return Response.status(Response.Status.NOT_FOUND).build();
+        }
+
+        return Response.ok().build();
+    }
+
+    /**
      * Get openstack vtap network.
      *
      * @return 200 OK with openstack vtap network
-     *         404 NOT_FOUND if openstackvtap network is not exists
+     *         404 NOT_FOUND if openstack vtap network is not exists
      * @onos.rsModel OpenstackVtapNetwork
      */
     @GET
@@ -123,7 +142,7 @@
     public Response getNetwork() {
         log.info(MESSAGE_NETWORK, READ);
 
-        OpenstackVtapNetwork vtapNetwork = vtapAdminService.getVtapNetwork();
+        OpenstackVtapNetwork vtapNetwork = vtapService.getVtapNetwork();
         if (vtapNetwork == null) {
             return Response.status(Response.Status.NOT_FOUND).build();
         }
@@ -132,25 +151,6 @@
         return Response.ok(jsonNode, MediaType.APPLICATION_JSON_TYPE).build();
     }
 
-    /**
-     * Removes openstack network.
-     *
-     * @return 200 OK on removing success
-     *         404 NOT_FOUND if openstackvtap network is not exists
-     * @onos.rsModel OpenstackVtapNetwork
-     */
-    @DELETE
-    @Consumes(MediaType.APPLICATION_JSON)
-    public Response deleteNetwork() {
-        log.info(MESSAGE_NETWORK, DELETE);
-
-        if (vtapAdminService.removeVtapNetwork() == null) {
-            return Response.status(Response.Status.NOT_FOUND).build();
-        }
-
-        return Response.ok().build();
-    }
-
     private OpenstackVtapNetwork readNetworkConfiguration(InputStream input) {
         try {
             JsonNode jsonTree = readTreeFromStream(mapper().enable(INDENT_OUTPUT), input);
diff --git a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/codec/OpenstackVtapNetworkCodecTest.java b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/codec/OpenstackVtapNetworkCodecTest.java
new file mode 100644
index 0000000..5a82d81
--- /dev/null
+++ b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/codec/OpenstackVtapNetworkCodecTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2018-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.onosproject.openstackvtap.codec;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.core.CoreService;
+import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
+import org.onosproject.openstackvtap.impl.DefaultOpenstackVtapNetwork;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onosproject.net.NetTestTools.APP_ID;
+import static org.onosproject.openstackvtap.codec.OpenstackVtapNetworkJsonMatcher.matchesVtapNetwork;
+
+/**
+ * Unit tests for OpenstackVtapNetwork codec.
+ */
+public class OpenstackVtapNetworkCodecTest {
+
+    MockCodecContext context;
+    JsonCodec<OpenstackVtapNetwork> vtapNetworkCodec;
+    final CoreService mockCoreService = createMock(CoreService.class);
+    private static final String REST_APP_ID = "org.onosproject.rest";
+
+    private static final OpenstackVtapNetwork.Mode MODE = OpenstackVtapNetwork.Mode.VXLAN;
+    private static final int VNI = 1;
+    private static final String SERVER_IP_ADDRESS = "10.10.10.1";
+
+    /**
+     * Initial setup for this unit test.
+     */
+    @Before
+    public void setUp() {
+        context = new MockCodecContext();
+        vtapNetworkCodec = new OpenstackVtapNetworkCodec();
+
+        assertThat(vtapNetworkCodec, notNullValue());
+
+        expect(mockCoreService.registerApplication(REST_APP_ID))
+                .andReturn(APP_ID).anyTimes();
+        replay(mockCoreService);
+        context.registerService(CoreService.class, mockCoreService);
+    }
+
+    /**
+     * Tests the openstack vtap network encoding.
+     */
+    @Test
+    public void testEncode() {
+        OpenstackVtapNetwork vtapNetwork = DefaultOpenstackVtapNetwork.builder()
+                .mode(MODE)
+                .networkId(VNI)
+                .serverIp(IpAddress.valueOf(SERVER_IP_ADDRESS))
+                .build();
+
+        ObjectNode nodeJson = vtapNetworkCodec.encode(vtapNetwork, context);
+        assertThat(nodeJson, matchesVtapNetwork(vtapNetwork));
+    }
+
+    /**
+     * Mock codec context for use in codec unit tests.
+     */
+    private class MockCodecContext implements CodecContext {
+        private final ObjectMapper mapper = new ObjectMapper();
+        private final CodecManager manager = new CodecManager();
+        private final Map<Class<?>, Object> services = new HashMap<>();
+
+        /**
+         * Constructs a new mock codec context.
+         */
+        public MockCodecContext() {
+            manager.activate();
+        }
+
+        @Override
+        public ObjectMapper mapper() {
+            return mapper;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public <T> JsonCodec<T> codec(Class<T> entityClass) {
+            if (entityClass == OpenstackVtapNetwork.class) {
+                return (JsonCodec<T>) vtapNetworkCodec;
+            }
+            return manager.getCodec(entityClass);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public <T> T getService(Class<T> serviceClass) {
+            return (T) services.get(serviceClass);
+        }
+
+        // for registering mock services
+        public <T> void registerService(Class<T> serviceClass, T impl) {
+            services.put(serviceClass, impl);
+        }
+    }
+}
diff --git a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/codec/OpenstackVtapNetworkJsonMatcher.java b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/codec/OpenstackVtapNetworkJsonMatcher.java
new file mode 100644
index 0000000..35e920a
--- /dev/null
+++ b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/codec/OpenstackVtapNetworkJsonMatcher.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2018-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.onosproject.openstackvtap.codec;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
+
+import java.util.Objects;
+
+/**
+ * Hamcrest matcher for openstack vtap network.
+ */
+public final class OpenstackVtapNetworkJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
+
+    private final OpenstackVtapNetwork vtapNetwork;
+
+    private static final String MODE = "mode";
+    private static final String NETWORK_ID = "networkId";
+    private static final String SERVER_IP = "serverIp";
+
+    private OpenstackVtapNetworkJsonMatcher(OpenstackVtapNetwork vtapNetwork) {
+        this.vtapNetwork = vtapNetwork;
+    }
+
+    @Override
+    protected boolean matchesSafely(JsonNode jsonNode, Description description) {
+
+        // check mode
+        String jsonMode = jsonNode.get(MODE).asText();
+        String mode = String.valueOf(vtapNetwork.mode());
+        if (!Objects.equals(jsonMode, mode)) {
+            description.appendText("mode was " + jsonMode);
+            return false;
+        }
+
+        // check network id
+        int jsonNetworkId = jsonNode.get(NETWORK_ID).asInt();
+        int networkId = vtapNetwork.networkId();
+        if (jsonNetworkId != networkId) {
+            description.appendText("network id was " + jsonNetworkId);
+            return false;
+        }
+
+        // check server IP
+        String jsonServerIp = jsonNode.get(SERVER_IP).asText();
+        String serverIp = vtapNetwork.serverIp().toString();
+        if (!jsonServerIp.equals(serverIp)) {
+            description.appendText("Server IP was " + jsonServerIp);
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public void describeTo(Description description) {
+        description.appendText(vtapNetwork.toString());
+    }
+
+    /**
+     * Factory to allocate an openstack vtap network matcher.
+     *
+     * @param vtapNetwork openstack vtap network object we are looking for
+     * @return matcher
+     */
+    public static OpenstackVtapNetworkJsonMatcher matchesVtapNetwork(OpenstackVtapNetwork vtapNetwork) {
+        return new OpenstackVtapNetworkJsonMatcher(vtapNetwork);
+    }
+}
diff --git a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapCriterionTest.java b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapCriterionTest.java
index 048a652..726b78e 100644
--- a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapCriterionTest.java
+++ b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapCriterionTest.java
@@ -18,6 +18,7 @@
 import com.google.common.testing.EqualsTester;
 import org.junit.Before;
 import org.junit.Test;
+import org.onlab.packet.IPv4;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.TpPort;
@@ -25,38 +26,40 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
 
 /**
- * Unit tests for DefaultOpenstackVtapCriterion.
+ * Unit tests for DefaultOpenstackVtapCriterion class.
  */
 public class DefaultOpenstackVtapCriterionTest {
 
     private static final IpPrefix SRC_IP_PREFIX_1 =
             IpPrefix.valueOf(IpAddress.valueOf("10.10.10.1"), 32);
     private static final IpPrefix SRC_IP_PREFIX_2 =
-            IpPrefix.valueOf(IpAddress.valueOf("20.20.20.1"), 32);
+            IpPrefix.valueOf(IpAddress.valueOf("10.10.20.1"), 32);
     private static final IpPrefix DST_IP_PREFIX_1 =
-            IpPrefix.valueOf(IpAddress.valueOf("10.10.10.2"), 32);
+            IpPrefix.valueOf(IpAddress.valueOf("10.10.30.2"), 32);
     private static final IpPrefix DST_IP_PREFIX_2 =
-            IpPrefix.valueOf(IpAddress.valueOf("20.20.20.2"), 32);
+            IpPrefix.valueOf(IpAddress.valueOf("10.10.40.2"), 32);
 
     private static final TpPort SRC_PORT_1 = TpPort.tpPort(10);
     private static final TpPort SRC_PORT_2 = TpPort.tpPort(20);
     private static final TpPort DST_PORT_1 = TpPort.tpPort(30);
     private static final TpPort DST_PORT_2 = TpPort.tpPort(40);
 
-    private static final byte IP_PROTOCOL_1 = (byte) 1;
-    private static final byte IP_PROTOCOL_2 = (byte) 2;
+    private static final byte IP_PROTOCOL_1 = IPv4.PROTOCOL_TCP;
+    private static final byte IP_PROTOCOL_2 = IPv4.PROTOCOL_UDP;
 
     private OpenstackVtapCriterion criterion1;
     private OpenstackVtapCriterion sameAsCriterion1;
     private OpenstackVtapCriterion criterion2;
 
+    /**
+     * Initial setup for this unit test.
+     */
     @Before
     public void setup() {
-
         OpenstackVtapCriterion.Builder builder1 = DefaultOpenstackVtapCriterion.builder();
-
         criterion1 = builder1
                         .srcIpPrefix(SRC_IP_PREFIX_1)
                         .dstIpPrefix(DST_IP_PREFIX_1)
@@ -66,7 +69,6 @@
                         .build();
 
         OpenstackVtapCriterion.Builder builder2 = DefaultOpenstackVtapCriterion.builder();
-
         sameAsCriterion1 = builder2
                         .srcIpPrefix(SRC_IP_PREFIX_1)
                         .dstIpPrefix(DST_IP_PREFIX_1)
@@ -76,7 +78,6 @@
                         .build();
 
         OpenstackVtapCriterion.Builder builder3 = DefaultOpenstackVtapCriterion.builder();
-
         criterion2 = builder3
                         .srcIpPrefix(SRC_IP_PREFIX_2)
                         .dstIpPrefix(DST_IP_PREFIX_2)
@@ -86,6 +87,17 @@
                         .build();
     }
 
+    /**
+     * Tests class immutability.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultOpenstackVtapCriterion.class);
+    }
+
+    /**
+     * Tests object equality.
+     */
     @Test
     public void testEquality() {
         new EqualsTester()
@@ -93,10 +105,12 @@
                 .addEqualityGroup(criterion2).testEquals();
     }
 
+    /**
+     * Tests object construction.
+     */
     @Test
     public void testConstruction() {
-        DefaultOpenstackVtapCriterion criterion =
-                                      (DefaultOpenstackVtapCriterion) criterion1;
+        OpenstackVtapCriterion criterion = criterion1;
 
         assertThat(criterion.srcIpPrefix(), is(SRC_IP_PREFIX_1));
         assertThat(criterion.dstIpPrefix(), is(DST_IP_PREFIX_1));
diff --git a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapNetworkTest.java b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapNetworkTest.java
new file mode 100644
index 0000000..393eb64
--- /dev/null
+++ b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapNetworkTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2018-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.onosproject.openstackvtap.impl;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Unit tests for DefaultOpenstackVtapNetwork class.
+ */
+public class DefaultOpenstackVtapNetworkTest {
+
+    private static final OpenstackVtapNetwork.Mode VTAP_NETWORK_MODE_1 = OpenstackVtapNetwork.Mode.VXLAN;
+    private static final OpenstackVtapNetwork.Mode VTAP_NETWORK_MODE_2 = OpenstackVtapNetwork.Mode.GRE;
+
+    private static final int VTAP_NETWORK_NETWORK_ID_1 = 1;
+    private static final int VTAP_NETWORK_NETWORK_ID_2 = 2;
+
+    private static final IpAddress SERVER_IP_1 = IpAddress.valueOf("20.10.10.1");
+    private static final IpAddress SERVER_IP_2 = IpAddress.valueOf("20.10.20.1");
+
+    private OpenstackVtapNetwork vtapNetwork1;
+    private OpenstackVtapNetwork sameAsVtapNetwork1;
+    private OpenstackVtapNetwork vtapNetwork2;
+
+    /**
+     * Initial setup for this unit test.
+     */
+    @Before
+    public void setup() {
+        OpenstackVtapNetwork.Builder builder1 = DefaultOpenstackVtapNetwork.builder();
+        vtapNetwork1 = builder1
+                .mode(VTAP_NETWORK_MODE_1)
+                .networkId(VTAP_NETWORK_NETWORK_ID_1)
+                .serverIp(SERVER_IP_1)
+                .build();
+
+        OpenstackVtapNetwork.Builder builder2 = DefaultOpenstackVtapNetwork.builder();
+        sameAsVtapNetwork1 = builder2
+                .mode(VTAP_NETWORK_MODE_1)
+                .networkId(VTAP_NETWORK_NETWORK_ID_1)
+                .serverIp(SERVER_IP_1)
+                .build();
+
+        OpenstackVtapNetwork.Builder builder3 = DefaultOpenstackVtapNetwork.builder();
+        vtapNetwork2 = builder3
+                .mode(VTAP_NETWORK_MODE_2)
+                .networkId(VTAP_NETWORK_NETWORK_ID_2)
+                .serverIp(SERVER_IP_2)
+                .build();
+    }
+
+    /**
+     * Tests class immutability.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultOpenstackVtapNetwork.class);
+    }
+
+    /**
+     * Tests object equality.
+     */
+    @Test
+    public void testEquality() {
+        new EqualsTester()
+                .addEqualityGroup(vtapNetwork1, sameAsVtapNetwork1)
+                .addEqualityGroup(vtapNetwork2).testEquals();
+    }
+
+    /**
+     * Tests object construction.
+     */
+    @Test
+    public void testConstruction() {
+        OpenstackVtapNetwork vtapNetwork = vtapNetwork1;
+
+        assertThat(vtapNetwork.mode(), is(VTAP_NETWORK_MODE_1));
+        assertThat(vtapNetwork.networkId(), is(VTAP_NETWORK_NETWORK_ID_1));
+        assertThat(vtapNetwork.serverIp(), is(SERVER_IP_1));
+    }
+}
diff --git a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapTest.java b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapTest.java
index 412d1d6..b65175f 100644
--- a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapTest.java
+++ b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/DefaultOpenstackVtapTest.java
@@ -15,30 +15,35 @@
  */
 package org.onosproject.openstackvtap.impl;
 
-import com.google.common.collect.Sets;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.testing.EqualsTester;
 import org.junit.Before;
 import org.junit.Test;
+import org.onlab.packet.IPv4;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.TpPort;
+import org.onosproject.net.DeviceId;
 import org.onosproject.openstackvtap.api.OpenstackVtap;
 import org.onosproject.openstackvtap.api.OpenstackVtapCriterion;
 import org.onosproject.openstackvtap.api.OpenstackVtapId;
 
+import java.util.Set;
+
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
 
 /**
- * Unit tests for DefaultOpenstackVtap.
+ * Unit tests for DefaultOpenstackVtap class.
  */
 public class DefaultOpenstackVtapTest {
 
     private static final OpenstackVtapId VTAP_ID_1 = OpenstackVtapId.vtapId();
     private static final OpenstackVtapId VTAP_ID_2 = OpenstackVtapId.vtapId();
 
-    private static final OpenstackVtap.Type VTAP_TYPE_1 = OpenstackVtap.Type.VTAP_TX;
-    private static final OpenstackVtap.Type VTAP_TYPE_2 = OpenstackVtap.Type.VTAP_RX;
+    private static final OpenstackVtap.Type VTAP_TYPE_1 = OpenstackVtap.Type.VTAP_ALL;
+    private static final OpenstackVtap.Type VTAP_TYPE_2 = OpenstackVtap.Type.VTAP_TX;
 
     private static final IpPrefix SRC_IP_PREFIX_1 =
             IpPrefix.valueOf(IpAddress.valueOf("10.10.10.1"), 32);
@@ -54,53 +59,76 @@
     private static final TpPort DST_PORT_1 = TpPort.tpPort(30);
     private static final TpPort DST_PORT_2 = TpPort.tpPort(40);
 
-    private static final byte IP_PROTOCOL_1 = (byte) 1;
-    private static final byte IP_PROTOCOL_2 = (byte) 2;
+    private static final byte IP_PROTOCOL_1 = IPv4.PROTOCOL_TCP;
+    private static final byte IP_PROTOCOL_2 = IPv4.PROTOCOL_UDP;
 
     private static final OpenstackVtapCriterion CRITERION_1 =
             createVtapCriterion(SRC_IP_PREFIX_1, DST_IP_PREFIX_1, SRC_PORT_1, DST_PORT_1, IP_PROTOCOL_1);
     private static final OpenstackVtapCriterion CRITERION_2 =
             createVtapCriterion(SRC_IP_PREFIX_2, DST_IP_PREFIX_2, SRC_PORT_2, DST_PORT_2, IP_PROTOCOL_2);
 
+    private static final DeviceId DEVICE_ID_1 = DeviceId.deviceId("of:00000000000000a1");
+    private static final DeviceId DEVICE_ID_2 = DeviceId.deviceId("of:00000000000000a2");
+    private static final DeviceId DEVICE_ID_3 = DeviceId.deviceId("of:00000000000000a3");
+    private static final DeviceId DEVICE_ID_4 = DeviceId.deviceId("of:00000000000000a4");
+    private static final DeviceId DEVICE_ID_5 = DeviceId.deviceId("of:00000000000000a5");
+    private static final DeviceId DEVICE_ID_6 = DeviceId.deviceId("of:00000000000000a6");
+    private static final DeviceId DEVICE_ID_7 = DeviceId.deviceId("of:00000000000000a7");
+    private static final DeviceId DEVICE_ID_8 = DeviceId.deviceId("of:00000000000000a8");
+
+    private static final Set<DeviceId> TX_DEVICE_IDS_1 = ImmutableSet.of(DEVICE_ID_1, DEVICE_ID_2);
+    private static final Set<DeviceId> RX_DEVICE_IDS_1 = ImmutableSet.of(DEVICE_ID_3, DEVICE_ID_4);
+    private static final Set<DeviceId> TX_DEVICE_IDS_2 = ImmutableSet.of(DEVICE_ID_5, DEVICE_ID_6);
+    private static final Set<DeviceId> RX_DEVICE_IDS_2 = ImmutableSet.of(DEVICE_ID_7, DEVICE_ID_8);
+
     private OpenstackVtap vtap1;
     private OpenstackVtap sameAsVtap1;
     private OpenstackVtap vtap2;
 
+    /**
+     * Initial setup for this unit test.
+     */
     @Before
     public void setup() {
-
         OpenstackVtap.Builder builder1 = DefaultOpenstackVtap.builder();
-
         vtap1 = builder1
                     .id(VTAP_ID_1)
                     .type(VTAP_TYPE_1)
                     .vtapCriterion(CRITERION_1)
-                    .txDeviceIds(Sets.newHashSet())
-                    .rxDeviceIds(Sets.newHashSet())
+                    .txDeviceIds(TX_DEVICE_IDS_1)
+                    .rxDeviceIds(RX_DEVICE_IDS_1)
                     .build();
 
         OpenstackVtap.Builder builder2 = DefaultOpenstackVtap.builder();
-
         sameAsVtap1 = builder2
                         .id(VTAP_ID_1)
                         .type(VTAP_TYPE_1)
                         .vtapCriterion(CRITERION_1)
-                        .txDeviceIds(Sets.newHashSet())
-                        .rxDeviceIds(Sets.newHashSet())
+                        .txDeviceIds(TX_DEVICE_IDS_1)
+                        .rxDeviceIds(RX_DEVICE_IDS_1)
                         .build();
 
         OpenstackVtap.Builder builder3 = DefaultOpenstackVtap.builder();
-
         vtap2 = builder3
                     .id(VTAP_ID_2)
                     .type(VTAP_TYPE_2)
                     .vtapCriterion(CRITERION_2)
-                    .txDeviceIds(Sets.newHashSet())
-                    .rxDeviceIds(Sets.newHashSet())
+                    .txDeviceIds(TX_DEVICE_IDS_2)
+                    .rxDeviceIds(RX_DEVICE_IDS_2)
                     .build();
-
     }
 
+    /**
+     * Tests class immutability.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultOpenstackVtap.class);
+    }
+
+    /**
+     * Tests object equality.
+     */
     @Test
     public void testEquality() {
         new EqualsTester()
@@ -108,24 +136,29 @@
                 .addEqualityGroup(vtap2).testEquals();
     }
 
+    /**
+     * Tests object construction.
+     */
     @Test
     public void testConstruction() {
-        DefaultOpenstackVtap vtap = (DefaultOpenstackVtap) vtap1;
+        OpenstackVtap vtap = vtap1;
 
         assertThat(vtap.id(), is(VTAP_ID_1));
         assertThat(vtap.vtapCriterion(), is(CRITERION_1));
         assertThat(vtap.type(), is(VTAP_TYPE_1));
+        assertThat(vtap.txDeviceIds(), is(TX_DEVICE_IDS_1));
+        assertThat(vtap.rxDeviceIds(), is(RX_DEVICE_IDS_1));
     }
 
     private static OpenstackVtapCriterion createVtapCriterion(IpPrefix srcIp, IpPrefix dstIp,
                                                               TpPort srcPort, TpPort dstPort,
                                                               byte ipProtocol) {
         return DefaultOpenstackVtapCriterion.builder()
-                                            .srcIpPrefix(srcIp)
-                                            .dstIpPrefix(dstIp)
-                                            .srcTpPort(srcPort)
-                                            .dstTpPort(dstPort)
-                                            .ipProtocol(ipProtocol)
-                                            .build();
+                .srcIpPrefix(srcIp)
+                .dstIpPrefix(dstIp)
+                .srcTpPort(srcPort)
+                .dstTpPort(dstPort)
+                .ipProtocol(ipProtocol)
+                .build();
     }
 }
diff --git a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapManagerTest.java b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapManagerTest.java
new file mode 100644
index 0000000..7624274
--- /dev/null
+++ b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapManagerTest.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2018-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.onosproject.openstackvtap.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onosproject.event.Event;
+import org.onosproject.openstackvtap.api.OpenstackVtap;
+import org.onosproject.store.service.TestStorageService;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.NetTestTools.injectEventDispatcher;
+import static org.onosproject.openstackvtap.api.OpenstackVtapEvent.Type.VTAP_ADDED;
+import static org.onosproject.openstackvtap.api.OpenstackVtapEvent.Type.VTAP_NETWORK_ADDED;
+import static org.onosproject.openstackvtap.api.OpenstackVtapEvent.Type.VTAP_NETWORK_REMOVED;
+import static org.onosproject.openstackvtap.api.OpenstackVtapEvent.Type.VTAP_REMOVED;
+import static org.onosproject.openstackvtap.api.OpenstackVtapEvent.Type.VTAP_UPDATED;
+
+/**
+ * Unit tests for openstack vtap manager.
+ */
+public class OpenstackVtapManagerTest extends OpenstackVtapTest {
+
+    private OpenstackVtapManager target;
+    private DistributedOpenstackVtapStore store;
+
+    private final TestOpenstackVtapListener testListener = new TestOpenstackVtapListener();
+
+    private void validateEvents(Enum... types) {
+        int i = 0;
+        assertEquals("Number of events did not match", types.length, testListener.events.size());
+        for (Event event : testListener.events) {
+            assertEquals("Incorrect event received", types[i], event.type());
+            i++;
+        }
+        testListener.events.clear();
+    }
+
+    @Before
+    public void setUp() {
+        store = new DistributedOpenstackVtapStore();
+        TestUtils.setField(store, "storageService", new TestStorageService());
+        store.activate();
+
+        store.createVtap(VTAP_2);
+
+        target = new OpenstackVtapManager();
+        target.coreService = new TestCoreService();
+        target.clusterService = new TestClusterService();
+        target.leadershipService = new TestLeadershipService();
+        target.flowRuleService = new TestFlowRuleService();
+        target.groupService = new TestGroupService();
+        target.deviceService = new TestDeviceService();
+        target.osNodeService = new TestOpenstackNodeService();
+        target.hostService = new TestHostService();
+        target.componentConfigService = new TestComponentConfigService();
+
+        target.store = store;
+        injectEventDispatcher(target, new TestEventDispatcher());
+        target.addListener(testListener);
+        testListener.events.clear();
+
+        target.activate();
+    }
+
+    @After
+    public void tearDown() {
+        target.clearVtap();
+        target.purgeVtap();
+
+        target.deactivate();
+        target.removeListener(testListener);
+        target = null;
+
+        store.deactivate();
+        store = null;
+    }
+
+    /**
+     * Checks if creating and removing a openstack vtap network work well with proper events.
+     */
+    @Test
+    public void testCreateAndRemoveVtapNetwork() {
+        target.createVtapNetwork(VTAP_NETWORK_MODE_1, VTAP_NETWORK_NETWORK_ID_1, SERVER_IP_1);
+        assertNotNull(target.getVtapNetwork());
+
+        target.removeVtapNetwork();
+        assertNull(target.getVtapNetwork());
+
+        validateEvents(VTAP_NETWORK_ADDED, VTAP_NETWORK_REMOVED);
+    }
+
+    /**
+     * Checks if creating null openstack vtap network fails with proper exception.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testCreateNullVtapNetwork() {
+        target.createVtapNetwork(null, null, null);
+    }
+
+    /**
+     * Checks if updating a null openstack vtap network fails with proper exception.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testUpdateNullVtapNetwork() {
+        target.updateVtapNetwork(null);
+    }
+
+    /**
+     * Checks if getting device ids by openstack vtap network returns correct.
+     */
+    @Test
+    public void testGetDeviceIdsFromVtapNetwork() {
+        store.createVtapNetwork(VTAP_NETWORK_KEY, VTAP_NETWORK_1);
+
+        store.addDeviceToVtapNetwork(VTAP_NETWORK_KEY, DEVICE_ID_1);
+        store.addDeviceToVtapNetwork(VTAP_NETWORK_KEY, DEVICE_ID_2);
+        assertTrue(ERR_NOT_FOUND, target.getVtapNetworkDevices().contains(DEVICE_ID_1));
+        assertTrue(ERR_NOT_FOUND, target.getVtapNetworkDevices().contains(DEVICE_ID_2));
+
+        store.removeDeviceFromVtapNetwork(VTAP_NETWORK_KEY, DEVICE_ID_1);
+        store.removeDeviceFromVtapNetwork(VTAP_NETWORK_KEY, DEVICE_ID_2);
+        assertTrue(ERR_NOT_FOUND, !target.getVtapNetworkDevices().contains(DEVICE_ID_1));
+        assertTrue(ERR_NOT_FOUND, !target.getVtapNetworkDevices().contains(DEVICE_ID_2));
+
+        store.removeVtapNetwork(VTAP_NETWORK_KEY);
+    }
+
+    /**
+     * Checks if creating and removing a openstack vtap work well with proper events.
+     */
+    @Test
+    public void testCreateAndRemoveVtap() {
+        OpenstackVtap vtap = target.createVtap(VTAP_TYPE_1, VTAP_CRITERION_1);
+        assertEquals(ERR_SIZE, 2, target.getVtapCount(OpenstackVtap.Type.VTAP_ANY));
+        assertNotNull(target.getVtap(vtap.id()));
+
+        target.removeVtap(vtap.id());
+        assertEquals(ERR_SIZE, 1, target.getVtapCount(OpenstackVtap.Type.VTAP_ANY));
+        assertNull(target.getVtap(vtap.id()));
+
+        validateEvents(VTAP_ADDED, VTAP_REMOVED);
+    }
+
+    /**
+     * Checks if updating a openstack vtap works well with proper event.
+     */
+    @Test
+    public void testUpdateVtap() {
+        OpenstackVtap updated = DefaultOpenstackVtap.builder(VTAP_2)
+                .vtapCriterion(VTAP_CRITERION_1)
+                .build();
+        target.updateVtap(updated);
+        assertEquals(ERR_NOT_MATCH, updated.vtapCriterion(), target.getVtap(VTAP_ID_2).vtapCriterion());
+
+        updated = DefaultOpenstackVtap.builder(VTAP_2)
+                .build();
+        target.updateVtap(updated);
+
+        validateEvents(VTAP_UPDATED, VTAP_UPDATED);
+    }
+
+    /**
+     * Checks if updating not existing openstack vtap fails with proper exception.
+     */
+    @Test
+    public void testUpdateNotExistingVtap() {
+        assertNull(target.updateVtap(VTAP_1));
+    }
+
+    /**
+     * Checks if creating null openstack vtap fails with proper exception.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testCreateNullVtap() {
+        target.createVtap(null, null);
+    }
+
+    /**
+     * Checks if updating a null openstack vtap fails with proper exception.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testUpdateNullVtap() {
+        target.updateVtap(null);
+    }
+
+    /**
+     * Checks if removing null openstack vtap fails with proper exception.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testRemoveNullVtap() {
+        target.removeVtap(null);
+    }
+
+    /**
+     * Checks if getting all by getVtaps method returns correct set of openstack vtaps.
+     */
+    @Test
+    public void testGetAllVtaps() {
+        assertEquals(ERR_SIZE, 1, target.getVtapCount(OpenstackVtap.Type.VTAP_ANY));
+        assertTrue(ERR_NOT_FOUND, target.getVtaps(OpenstackVtap.Type.VTAP_ANY).contains(VTAP_2));
+    }
+
+    /**
+     * Checks if getting device ids by openstack vtap returns correct.
+     */
+    @Test
+    public void testGetDeviceIdsFromVtap() {
+        assertTrue(ERR_NOT_FOUND, target.getVtapsByDeviceId(DEVICE_ID_3).contains(VTAP_2));
+        assertTrue(ERR_NOT_FOUND, target.getVtapsByDeviceId(DEVICE_ID_4).contains(VTAP_2));
+    }
+
+}
diff --git a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapStoreTest.java b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapStoreTest.java
new file mode 100644
index 0000000..f865685
--- /dev/null
+++ b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapStoreTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2018-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.onosproject.openstackvtap.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onosproject.openstackvtap.api.OpenstackVtap;
+import org.onosproject.store.service.TestStorageService;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Unit tests for openstack vtap distributed store.
+ */
+public class OpenstackVtapStoreTest extends OpenstackVtapTest {
+
+    private DistributedOpenstackVtapStore store;
+
+    @Before
+    public void setup() {
+        store = new DistributedOpenstackVtapStore();
+        TestUtils.setField(store, "storageService", new TestStorageService());
+        store.activate();
+    }
+
+    @After
+    public void tearDown() {
+        store.deactivate();
+        store = null;
+    }
+
+    /**
+     * Create, update and remove a openstack vtap network to the store;
+     * checks if openstack vtap network store is correct.
+     */
+    @Test
+    public void testCreateUpdateAndRemoveVtapNetwork() {
+        store.createVtapNetwork(VTAP_NETWORK_KEY, VTAP_NETWORK_1);
+        assertEquals(ERR_NOT_MATCH, store.getVtapNetwork(VTAP_NETWORK_KEY), VTAP_NETWORK_1);
+
+        store.updateVtapNetwork(VTAP_NETWORK_KEY, VTAP_NETWORK_2);
+        assertEquals(ERR_NOT_MATCH, store.getVtapNetwork(VTAP_NETWORK_KEY), VTAP_NETWORK_2);
+
+        store.removeVtapNetwork(VTAP_NETWORK_KEY);
+        assertNull(store.getVtapNetwork(VTAP_NETWORK_KEY));
+    }
+
+    /**
+     * Clear all openstack vtap network of the store; checks if openstack vtap network store is empty.
+     */
+    @Test
+    public void testClearVtapNetworks() {
+        store.clearVtapNetworks();
+        assertEquals(ERR_SIZE, 0, store.getVtapNetworkCount());
+    }
+
+    /**
+     * Checks if getting device ids by openstack vtap network returns correct.
+     */
+    @Test
+    public void testGetDeviceIdsFromVtapNetwork() {
+        store.createVtapNetwork(VTAP_NETWORK_KEY, VTAP_NETWORK_1);
+
+        store.addDeviceToVtapNetwork(VTAP_NETWORK_KEY, DEVICE_ID_1);
+        store.addDeviceToVtapNetwork(VTAP_NETWORK_KEY, DEVICE_ID_2);
+        assertTrue(ERR_NOT_FOUND, store.getVtapNetworkDevices(VTAP_NETWORK_KEY).contains(DEVICE_ID_1));
+        assertTrue(ERR_NOT_FOUND, store.getVtapNetworkDevices(VTAP_NETWORK_KEY).contains(DEVICE_ID_2));
+
+        store.removeDeviceFromVtapNetwork(VTAP_NETWORK_KEY, DEVICE_ID_1);
+        store.removeDeviceFromVtapNetwork(VTAP_NETWORK_KEY, DEVICE_ID_2);
+        assertTrue(ERR_NOT_FOUND, !store.getVtapNetworkDevices(VTAP_NETWORK_KEY).contains(DEVICE_ID_1));
+        assertTrue(ERR_NOT_FOUND, !store.getVtapNetworkDevices(VTAP_NETWORK_KEY).contains(DEVICE_ID_2));
+
+        store.removeVtapNetwork(VTAP_NETWORK_KEY);
+    }
+
+    /**
+     * Create, update and remove a openstack vtap to the store;
+     * checks if openstack vtap store is correct.
+     */
+    @Test
+    public void testCreateUpdateAndRemoveVtap() {
+        store.createVtap(VTAP_1);
+        assertTrue(ERR_NOT_FOUND, store.getVtaps(OpenstackVtap.Type.VTAP_ANY).contains(VTAP_1));
+        assertEquals(ERR_NOT_MATCH, store.getVtap(VTAP_ID_1), VTAP_1);
+
+        OpenstackVtap updated = DefaultOpenstackVtap.builder(VTAP_1)
+                .vtapCriterion(VTAP_CRITERION_2)
+                .build();
+        store.updateVtap(updated, true);
+        assertEquals(ERR_NOT_MATCH, updated, store.getVtap(VTAP_ID_1));
+
+        store.removeVtap(VTAP_ID_1);
+        assertNull(store.getVtap(VTAP_ID_1));
+    }
+
+    /**
+     * Checks if getting all by getVtaps method returns correct set of openstack vtaps.
+     */
+    @Test
+    public void testClearVtaps() {
+        store.clearVtaps();
+        assertEquals(ERR_SIZE, 0, store.getVtapCount(OpenstackVtap.Type.VTAP_ANY));
+        assertEquals(ERR_SIZE, 0, store.getVtaps(OpenstackVtap.Type.VTAP_ANY).size());
+    }
+
+    /**
+     * Checks if getting device ids by openstack vtap returns correct.
+     */
+    @Test
+    public void testGetDeviceIdsFromVtap() {
+        store.createVtap(VTAP_2);
+
+        store.addDeviceToVtap(VTAP_ID_2, OpenstackVtap.Type.VTAP_TX, DEVICE_ID_3);
+        store.addDeviceToVtap(VTAP_ID_2, OpenstackVtap.Type.VTAP_RX, DEVICE_ID_4);
+        assertTrue(ERR_NOT_FOUND, store.getVtapsByDeviceId(DEVICE_ID_3).contains(VTAP_2));
+        assertTrue(ERR_NOT_FOUND, store.getVtapsByDeviceId(DEVICE_ID_4).contains(VTAP_2));
+
+        store.removeDeviceFromVtap(VTAP_ID_2, OpenstackVtap.Type.VTAP_TX, DEVICE_ID_3);
+        store.removeDeviceFromVtap(VTAP_ID_2, OpenstackVtap.Type.VTAP_RX, DEVICE_ID_4);
+        assertTrue(ERR_NOT_FOUND, !store.getVtapsByDeviceId(DEVICE_ID_3).contains(VTAP_2));
+        assertTrue(ERR_NOT_FOUND, !store.getVtapsByDeviceId(DEVICE_ID_4).contains(VTAP_2));
+
+        store.removeVtap(VTAP_ID_2);
+    }
+
+}
diff --git a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapTest.java b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapTest.java
new file mode 100644
index 0000000..dfd927a
--- /dev/null
+++ b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapTest.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2018-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.onosproject.openstackvtap.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.TpPort;
+import org.onosproject.TestApplicationId;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.cfg.ConfigProperty;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.LeadershipServiceAdapter;
+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.DeviceId;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.flow.FlowRuleServiceAdapter;
+import org.onosproject.net.group.GroupServiceAdapter;
+import org.onosproject.net.host.HostServiceAdapter;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeListener;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
+import org.onosproject.openstackvtap.api.OpenstackVtap;
+import org.onosproject.openstackvtap.api.OpenstackVtapCriterion;
+import org.onosproject.openstackvtap.api.OpenstackVtapEvent;
+import org.onosproject.openstackvtap.api.OpenstackVtapId;
+import org.onosproject.openstackvtap.api.OpenstackVtapListener;
+import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
+
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Provides a set of test OpenstackVtapNetwork, OpenstackVtap parameters
+ * for use with OpenstackVtapNetwork, OpenstackVtap related tests.
+ */
+public abstract class OpenstackVtapTest {
+
+    protected static final String APP_NAME = "org.onosproject.openstackvtap";
+    protected static final ApplicationId APP_ID = TestApplicationId.create(APP_NAME);
+
+    protected static final String ERR_SIZE = "Number of vtap or vtap network did not match";
+    protected static final String ERR_NOT_MATCH = "Vtap or vtap network did not match";
+    protected static final String ERR_NOT_FOUND = "Vtap or vtap network did not exist";
+
+    protected static final int VTAP_NETWORK_KEY = 0;
+
+    protected static final OpenstackVtapNetwork.Mode VTAP_NETWORK_MODE_1 = OpenstackVtapNetwork.Mode.VXLAN;
+    protected static final OpenstackVtapNetwork.Mode VTAP_NETWORK_MODE_2 = OpenstackVtapNetwork.Mode.GRE;
+
+    protected static final int VTAP_NETWORK_NETWORK_ID_1 = 1;
+    protected static final int VTAP_NETWORK_NETWORK_ID_2 = 2;
+
+    protected static final IpAddress SERVER_IP_1 = IpAddress.valueOf("20.10.10.1");
+    protected static final IpAddress SERVER_IP_2 = IpAddress.valueOf("20.10.20.1");
+
+    protected static final OpenstackVtapNetwork VTAP_NETWORK_1 =
+            createVtapNetwork(VTAP_NETWORK_MODE_1, VTAP_NETWORK_NETWORK_ID_1, SERVER_IP_1);
+    protected static final OpenstackVtapNetwork VTAP_NETWORK_2 =
+            createVtapNetwork(VTAP_NETWORK_MODE_2, VTAP_NETWORK_NETWORK_ID_2, SERVER_IP_2);
+
+    protected static final IpPrefix SRC_IP_PREFIX_1 =
+            IpPrefix.valueOf(IpAddress.valueOf("10.10.10.1"), 32);
+    protected static final IpPrefix SRC_IP_PREFIX_2 =
+            IpPrefix.valueOf(IpAddress.valueOf("10.10.20.1"), 32);
+    protected static final IpPrefix DST_IP_PREFIX_1 =
+            IpPrefix.valueOf(IpAddress.valueOf("10.10.30.2"), 32);
+    protected static final IpPrefix DST_IP_PREFIX_2 =
+            IpPrefix.valueOf(IpAddress.valueOf("10.10.40.2"), 32);
+
+    protected static final TpPort SRC_PORT_1 = TpPort.tpPort(10);
+    protected static final TpPort SRC_PORT_2 = TpPort.tpPort(20);
+    protected static final TpPort DST_PORT_1 = TpPort.tpPort(30);
+    protected static final TpPort DST_PORT_2 = TpPort.tpPort(40);
+
+    protected static final byte IP_PROTOCOL_1 = IPv4.PROTOCOL_TCP;
+    protected static final byte IP_PROTOCOL_2 = IPv4.PROTOCOL_UDP;
+
+    protected static final OpenstackVtapCriterion VTAP_CRITERION_1 =
+            createCriterion(SRC_IP_PREFIX_1, DST_IP_PREFIX_1, SRC_PORT_1, DST_PORT_1, IP_PROTOCOL_1);
+    protected static final OpenstackVtapCriterion VTAP_CRITERION_2 =
+            createCriterion(SRC_IP_PREFIX_2, DST_IP_PREFIX_2, SRC_PORT_2, DST_PORT_2, IP_PROTOCOL_2);
+
+    protected static final OpenstackVtapId VTAP_ID_1 = OpenstackVtapId.vtapId();
+    protected static final OpenstackVtapId VTAP_ID_2 = OpenstackVtapId.vtapId();
+
+    protected static final OpenstackVtap.Type VTAP_TYPE_1 = OpenstackVtap.Type.VTAP_ALL;
+    protected static final OpenstackVtap.Type VTAP_TYPE_2 = OpenstackVtap.Type.VTAP_TX;
+
+    protected static final DeviceId DEVICE_ID_1 = DeviceId.deviceId("of:00000000000000a1");
+    protected static final DeviceId DEVICE_ID_2 = DeviceId.deviceId("of:00000000000000a2");
+    protected static final DeviceId DEVICE_ID_3 = DeviceId.deviceId("of:00000000000000a3");
+    protected static final DeviceId DEVICE_ID_4 = DeviceId.deviceId("of:00000000000000a4");
+
+    protected static final Set<DeviceId> TX_DEVICE_IDS_1 = ImmutableSet.of(DEVICE_ID_1);
+    protected static final Set<DeviceId> RX_DEVICE_IDS_1 = ImmutableSet.of(DEVICE_ID_2);
+    protected static final Set<DeviceId> TX_DEVICE_IDS_2 = ImmutableSet.of(DEVICE_ID_3);
+    protected static final Set<DeviceId> RX_DEVICE_IDS_2 = ImmutableSet.of(DEVICE_ID_4);
+
+    protected static final OpenstackVtap VTAP_1 =
+            createVtap(VTAP_ID_1, VTAP_TYPE_1, VTAP_CRITERION_1, TX_DEVICE_IDS_1, RX_DEVICE_IDS_1);
+    protected static final OpenstackVtap VTAP_2 =
+            createVtap(VTAP_ID_2, VTAP_TYPE_2, VTAP_CRITERION_2, TX_DEVICE_IDS_2, RX_DEVICE_IDS_2);
+
+
+    public static class TestOpenstackVtapListener implements OpenstackVtapListener {
+        public List<OpenstackVtapEvent> events = Lists.newArrayList();
+
+        @Override
+        public void event(OpenstackVtapEvent event) {
+            events.add(event);
+        }
+    }
+
+    public static class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return APP_ID;
+        }
+    }
+
+    public static class TestClusterService extends ClusterServiceAdapter {
+
+    }
+
+    public static class TestLeadershipService extends LeadershipServiceAdapter {
+
+    }
+
+    public static class TestFlowRuleService extends FlowRuleServiceAdapter {
+
+    }
+
+    public static class TestGroupService extends GroupServiceAdapter {
+
+    }
+
+    public static class TestDeviceService extends DeviceServiceAdapter {
+
+    }
+
+    public static class TestOpenstackNodeService implements OpenstackNodeService {
+
+        @Override
+        public Set<OpenstackNode> nodes() {
+            return ImmutableSet.of();
+        }
+
+        @Override
+        public Set<OpenstackNode> nodes(OpenstackNode.NodeType type) {
+            return ImmutableSet.of();
+        }
+
+        @Override
+        public Set<OpenstackNode> completeNodes() {
+            return ImmutableSet.of();
+        }
+
+        @Override
+        public Set<OpenstackNode> completeNodes(OpenstackNode.NodeType type) {
+            return ImmutableSet.of();
+        }
+
+        @Override
+        public OpenstackNode node(String hostname) {
+            return null;
+        }
+
+        @Override
+        public OpenstackNode node(DeviceId deviceId) {
+            return null;
+        }
+
+        @Override
+        public void addVfPort(OpenstackNode osNode, String portName) {
+        }
+
+        @Override
+        public void removeVfPort(OpenstackNode osNode, String portName) {
+        }
+
+
+        @Override
+        public void addListener(OpenstackNodeListener listener) {
+
+        }
+
+        @Override
+        public void removeListener(OpenstackNodeListener listener) {
+
+        }
+    }
+
+    public static class TestHostService extends HostServiceAdapter {
+
+    }
+
+    public static class TestComponentConfigService 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 unsetProperty(String componentName, String name) {
+        }
+
+        @Override
+        public ConfigProperty getProperty(String componentName, String attribute) {
+            return null;
+        }
+    }
+
+    /**
+     * A mock of event dispatcher.
+     */
+    public 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;
+        }
+    }
+
+    public static OpenstackVtapNetwork createVtapNetwork(OpenstackVtapNetwork.Mode mode,
+                                                         Integer networkId,
+                                                         IpAddress serverIp) {
+        return DefaultOpenstackVtapNetwork.builder()
+                .mode(mode)
+                .networkId(networkId)
+                .serverIp(serverIp)
+                .build();
+    }
+
+    public static OpenstackVtap createVtap(OpenstackVtapId id,
+                                           OpenstackVtap.Type type,
+                                           OpenstackVtapCriterion vtapCriterion,
+                                           Set<DeviceId> txDevices,
+                                           Set<DeviceId> rxDevices) {
+        return DefaultOpenstackVtap.builder()
+                .id(id)
+                .type(type)
+                .vtapCriterion(vtapCriterion)
+                .txDeviceIds(txDevices)
+                .rxDeviceIds(rxDevices)
+                .build();
+    }
+
+    public static OpenstackVtapCriterion createCriterion(IpPrefix srcIpPrefix, IpPrefix dstIpPrefix,
+                                                         TpPort srcPort, TpPort dstPort,
+                                                         byte ipProtocol) {
+        return DefaultOpenstackVtapCriterion.builder()
+                .srcIpPrefix(srcIpPrefix)
+                .dstIpPrefix(dstIpPrefix)
+                .srcTpPort(srcPort)
+                .dstTpPort(dstPort)
+                .ipProtocol(ipProtocol)
+                .build();
+    }
+
+}
diff --git a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/web/OpenstackVtapNetworkCodecRegisterTest.java b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/web/OpenstackVtapNetworkCodecRegisterTest.java
new file mode 100644
index 0000000..b9766ad
--- /dev/null
+++ b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/web/OpenstackVtapNetworkCodecRegisterTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018-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.onosproject.openstackvtap.web;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
+import org.onosproject.openstackvtap.codec.OpenstackVtapNetworkCodec;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Unit test for openstack vtap network codec register.
+ */
+public final class OpenstackVtapNetworkCodecRegisterTest {
+
+    private OpenstackVtapNetworkCodecRegister register;
+
+    /**
+     * Tests codec register activation and deactivation.
+     */
+    @Test
+    public void testActivateDeactivate() {
+        register = new OpenstackVtapNetworkCodecRegister();
+        CodecService codecService = new TestCodecService();
+
+        TestUtils.setField(register, "codecService", codecService);
+        register.activate();
+
+        assertEquals(OpenstackVtapNetworkCodec.class.getName(),
+                codecService.getCodec(OpenstackVtapNetwork.class).getClass().getName());
+
+        register.deactivate();
+
+        assertNull(codecService.getCodec(OpenstackVtapNetwork.class));
+    }
+
+    private static class TestCodecService implements CodecService {
+
+        private Map<String, JsonCodec> codecMap = Maps.newConcurrentMap();
+
+        @Override
+        public Set<Class<?>> getCodecs() {
+            return ImmutableSet.of();
+        }
+
+        @Override
+        public <T> JsonCodec<T> getCodec(Class<T> entityClass) {
+            return codecMap.get(entityClass.getName());
+        }
+
+        @Override
+        public <T> void registerCodec(Class<T> entityClass, JsonCodec<T> codec) {
+            codecMap.put(entityClass.getName(), codec);
+        }
+
+        @Override
+        public void unregisterCodec(Class<?> entityClass) {
+            codecMap.remove(entityClass.getName());
+        }
+    }
+}
diff --git a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/web/OpenstackVtapNetworkWebResourceTest.java b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/web/OpenstackVtapNetworkWebResourceTest.java
new file mode 100644
index 0000000..4e821b2
--- /dev/null
+++ b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/web/OpenstackVtapNetworkWebResourceTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2018-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.onosproject.openstackvtap.web;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
+import org.onosproject.openstackvtap.api.OpenstackVtapService;
+import org.onosproject.openstackvtap.codec.OpenstackVtapNetworkCodec;
+import org.onosproject.openstackvtap.impl.DefaultOpenstackVtapNetwork;
+import org.onosproject.rest.resources.ResourceTest;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit test for openstack vtap network REST API.
+ */
+public class OpenstackVtapNetworkWebResourceTest extends ResourceTest {
+
+    final OpenstackVtapService mockVtapService = createMock(OpenstackVtapService.class);
+    private static final String PATH = "vtap-network";
+
+    /**
+     * Constructs an openstack vtap network resource test instance.
+     */
+    public OpenstackVtapNetworkWebResourceTest() {
+        super(ResourceConfig.forApplicationClass(OpenstackVtapWebApplication.class));
+    }
+
+    private OpenstackVtapNetwork vtapNetwork;
+
+    /**
+     * Sets up the global values for all the tests.
+     */
+    @Before
+    public void setUpTest() {
+        final CodecManager codecService = new CodecManager();
+        codecService.activate();
+        codecService.registerCodec(OpenstackVtapNetwork.class, new OpenstackVtapNetworkCodec());
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(OpenstackVtapService.class, mockVtapService)
+                        .add(CodecService.class, codecService);
+        setServiceDirectory(testDirectory);
+
+        vtapNetwork = DefaultOpenstackVtapNetwork.builder()
+                .mode(OpenstackVtapNetwork.Mode.VXLAN)
+                .networkId(1)
+                .serverIp(IpAddress.valueOf("10.10.10.1"))
+                .build();
+    }
+
+    /**
+     * Tests the results of the REST API POST method with creating new vtap network operation.
+     */
+    @Test
+    public void testCreateVtapNetworkWithCreateOperation() {
+        expect(mockVtapService.createVtapNetwork(anyObject(), anyObject(), anyObject()))
+                .andReturn(vtapNetwork).once();
+        replay(mockVtapService);
+
+        final WebTarget wt = target();
+        InputStream jsonStream = OpenstackVtapNetworkWebResourceTest.class
+                .getResourceAsStream("openstack-vtap-config.json");
+        Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        final int status = response.getStatus();
+
+        assertThat(status, is(200));
+
+        verify(mockVtapService);
+    }
+
+    /**
+     * Tests the results of the REST API POST method without creating new vtap network operation.
+     */
+    @Test
+    public void testCreateVtapNetworkWithoutCreateOperation() {
+        final WebTarget wt = target();
+        InputStream jsonStream = OpenstackVtapNetworkWebResourceTest.class
+                .getResourceAsStream("openstack-vtap-config.json");
+        Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        final int status = response.getStatus();
+
+        assertThat(status, is(409));
+    }
+
+    /**
+     * Tests the results of the REST API PUT method with modifying the vtap network.
+     */
+    @Test
+    public void testUpdateVtapNetworkWithoutModifyOperation() {
+        expect(mockVtapService.updateVtapNetwork(anyObject())).andReturn(vtapNetwork).once();
+        replay(mockVtapService);
+
+        final WebTarget wt = target();
+        InputStream jsonStream = OpenstackVtapNetworkWebResourceTest.class
+                .getResourceAsStream("openstack-vtap-config.json");
+        Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+                .put(Entity.json(jsonStream));
+        final int status = response.getStatus();
+
+        assertThat(status, is(200));
+
+        verify(mockVtapService);
+    }
+
+    /**
+     * Tests the results of the REST API PUT method without modifying the vtap network.
+     */
+    @Test
+    public void testUpdateVtapNetworkWithModifyOperation() {
+        final WebTarget wt = target();
+        InputStream jsonStream = OpenstackVtapNetworkWebResourceTest.class
+                .getResourceAsStream("openstack-vtap-config.json");
+        Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+                .put(Entity.json(jsonStream));
+        final int status = response.getStatus();
+
+        assertThat(status, is(404));
+    }
+
+    /**
+     * Tests the results of the REST API DELETE method with deleting the vtap network.
+     */
+    @Test
+    public void testDeleteVtapNetworkWithDeletionOperation() {
+        expect(mockVtapService.removeVtapNetwork()).andReturn(vtapNetwork).once();
+        replay(mockVtapService);
+
+        final WebTarget wt = target();
+        Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        final int status = response.getStatus();
+
+        assertThat(status, is(200));
+
+        verify(mockVtapService);
+    }
+
+    /**
+     * Tests the results of the REST API DELETE method without deleting the vtap network.
+     */
+    @Test
+    public void testDeleteVtapNetworkWithoutDeletionOperation() {
+        final WebTarget wt = target();
+        Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        final int status = response.getStatus();
+
+        assertThat(status, is(404));
+    }
+
+    /**
+     * Tests the results of the REST API GET method with getting the vtap network.
+     */
+    @Test
+    public void testGetVtapNetworkWithGetOperation() {
+        expect(mockVtapService.getVtapNetwork()).andReturn(vtapNetwork).once();
+        replay(mockVtapService);
+
+        final WebTarget wt = target();
+        Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+                .get();
+
+        final int status = response.getStatus();
+
+        assertThat(status, is(200));
+
+        verify(mockVtapService);
+    }
+
+    /**
+     * Tests the results of the REST API GET method without getting the vtap network.
+     */
+    @Test
+    public void testGetVtapNetworkWithoutGetOperation() {
+        final WebTarget wt = target();
+        Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+                .get();
+
+        final int status = response.getStatus();
+
+        assertThat(status, is(404));
+    }
+
+}
diff --git a/apps/openstackvtap/app/src/test/resources/org/onosproject/openstackvtap/web/openstack-vtap-config.json b/apps/openstackvtap/app/src/test/resources/org/onosproject/openstackvtap/web/openstack-vtap-config.json
new file mode 100644
index 0000000..44ebc5c
--- /dev/null
+++ b/apps/openstackvtap/app/src/test/resources/org/onosproject/openstackvtap/web/openstack-vtap-config.json
@@ -0,0 +1,7 @@
+{
+  "network": {
+    "mode": "VXLAN",
+    "networkId": 1,
+    "serverIp": "10.10.10.1"
+  }
+}
\ No newline at end of file