diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/AbstractVirtualListenerManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/AbstractVirtualListenerManagerTest.java
new file mode 100644
index 0000000..bc0d32e
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/AbstractVirtualListenerManagerTest.java
@@ -0,0 +1,310 @@
+/*
+ * 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.incubator.net.virtual;
+
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.MutableClassToInstanceMap;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.event.Event;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.event.EventListener;
+import org.onosproject.event.EventSink;
+import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
+import org.onosproject.incubator.net.virtual.event.VirtualEvent;
+import org.onosproject.incubator.net.virtual.event.VirtualListenerRegistryManager;
+import org.onosproject.net.TenantId;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.*;
+
+/**
+ * Test of the virtual event dispatcher mechanism.
+ */
+public class AbstractVirtualListenerManagerTest {
+
+    private TestEventDispatcher dispatcher = new TestEventDispatcher();
+    private VirtualListenerRegistryManager listenerRegistryManager =
+            VirtualListenerRegistryManager.getInstance();
+
+    private PrickleManager prickleManager;
+    private PrickleListener prickleListener;
+
+    private GooManager gooManager;
+    private GooListener gooListener;
+
+    private BarManager barManager;
+    private BarListener barListener;
+
+    @Before
+    public void setUp() {
+        VirtualNetworkService manager = new TestVirtualNetworkManager();
+
+        dispatcher.addSink(VirtualEvent.class, listenerRegistryManager);
+
+        prickleListener = new PrickleListener();
+        prickleManager = new PrickleManager(manager, NetworkId.networkId(1));
+        prickleManager.addListener(prickleListener);
+
+        gooListener = new GooListener();
+        gooManager = new GooManager(manager, NetworkId.networkId(1));
+        gooManager.addListener(gooListener);
+
+        barListener = new BarListener();
+        barManager = new BarManager(manager, NetworkId.networkId(2));
+        barManager.addListener(barListener);
+    }
+
+    @After
+    public void tearDown() {
+        dispatcher.removeSink(VirtualEvent.class);
+
+        prickleListener.events.clear();
+        gooListener.events.clear();
+        barListener.events.clear();
+
+        prickleListener.latch = null;
+        gooListener.latch = null;
+        barListener.latch = null;
+    }
+
+    @Test
+    public void postPrickle() throws InterruptedException {
+        prickleListener.latch = new CountDownLatch(1);
+        prickleManager.post(new Prickle("prickle"));
+        prickleListener.latch.await(100, TimeUnit.MILLISECONDS);
+
+        validate(prickleListener, "prickle");
+        validate(gooListener);
+        validate(barListener);
+    }
+
+    @Test
+    public void postGoo() throws InterruptedException {
+        gooListener.latch = new CountDownLatch(1);
+        gooManager.post(new Goo("goo"));
+        gooListener.latch.await(100, TimeUnit.MILLISECONDS);
+
+        validate(prickleListener);
+        validate(gooListener, "goo");
+        validate(barListener);
+    }
+
+    @Test
+    public void postBar() throws InterruptedException {
+        barListener.latch = new CountDownLatch(1);
+        barManager.post(new Bar("bar"));
+        barListener.latch.await(100, TimeUnit.MILLISECONDS);
+
+        validate(prickleListener);
+        validate(gooListener);
+        validate(barListener, "bar");
+    }
+
+    @Test
+    public void postEventWithNoListener() throws Exception {
+        dispatcher.post(new Thing("boom"));
+
+        validate(prickleListener);
+        validate(gooListener);
+        validate(barListener);
+    }
+
+    private void validate(TestListener listener, String... strings) {
+        int i = 0;
+        assertEquals("incorrect event count", strings.length, listener.events.size());
+        for (String string : strings) {
+            Event event = (Event) listener.events.get(i++);
+            assertEquals("incorrect event", string, event.subject());
+        }
+    }
+
+    private enum Type { FOO }
+
+    private static class Thing extends AbstractEvent<Type, String> {
+        protected Thing(String subject) {
+            super(Type.FOO, subject);
+        }
+    }
+
+    private static final class Prickle extends Thing {
+        private Prickle(String subject) {
+            super(subject);
+        }
+    }
+
+    private static final class Goo extends Thing {
+        private Goo(String subject) {
+            super(subject);
+        }
+    }
+
+    private static final class Bar extends Thing {
+        private Bar(String subject) {
+            super(subject);
+        }
+    }
+
+    private class TestListener<E extends Event> implements EventListener<E> {
+        List<E> events = new ArrayList<>();
+        CountDownLatch latch;
+
+        @Override
+        public void event(E event) {
+            events.add(event);
+            latch.countDown();
+        }
+    }
+
+    private class PrickleListener extends TestListener<Prickle> {
+    }
+
+    private class GooListener extends TestListener<Goo> {
+    }
+
+    private class BarListener extends TestListener<Bar> {
+    }
+
+    private class PrickleManager extends AbstractVirtualListenerManager<Prickle, PrickleListener> {
+        public PrickleManager(VirtualNetworkService service, NetworkId networkId) {
+            super(service, networkId, Prickle.class);
+        }
+
+        @Override
+        protected void post(Prickle event) {
+            super.post(event);
+        }
+    }
+
+    private class GooManager extends AbstractVirtualListenerManager<Goo, GooListener> {
+        public GooManager(VirtualNetworkService service, NetworkId networkId) {
+            super(service, networkId, Goo.class);
+        }
+
+        @Override
+        protected void post(Goo event) {
+            super.post(event);
+        }
+    }
+
+    private class BarManager extends AbstractVirtualListenerManager<Bar, BarListener> {
+        public BarManager(VirtualNetworkService service, NetworkId networkId) {
+            super(service, networkId, Bar.class);
+        }
+
+        @Override
+        protected void post(Bar event) {
+            super.post(event);
+        }
+    }
+
+
+    private class TestEventDispatcher implements EventDeliveryService {
+        private EventSink sink;
+
+        @Override
+        public <E extends Event> void addSink(Class<E> eventClass, EventSink<E> sink) {
+            this.sink = sink;
+        }
+
+        @Override
+        public <E extends Event> void removeSink(Class<E> eventClass) {
+            this.sink = null;
+        }
+
+        @Override
+        public <E extends Event> EventSink<E> getSink(Class<E> eventClass) {
+            return null;
+        }
+
+        @Override
+        public Set<Class<? extends Event>> getSinks() {
+            return null;
+        }
+
+        @Override
+        public void setDispatchTimeLimit(long millis) {
+
+        }
+
+        @Override
+        public long getDispatchTimeLimit() {
+            return 0;
+        }
+
+        @Override
+        public void post(Event event) {
+            if (event instanceof VirtualEvent) {
+                sink.process(event);
+            }
+        }
+    }
+
+    private class TestVirtualNetworkManager extends VirtualNetworkServiceAdapter {
+        TestServiceDirectory serviceDirectory = new TestServiceDirectory();
+
+        public TestVirtualNetworkManager() {
+            serviceDirectory.add(EventDeliveryService.class, dispatcher);
+        }
+
+        @Override
+        public VirtualNetwork getVirtualNetwork(NetworkId networkId) {
+            return null;
+        }
+
+        @Override
+        public TenantId getTenantId(NetworkId networkId) {
+            return null;
+        }
+
+        @Override
+        public ServiceDirectory getServiceDirectory() {
+            return serviceDirectory;
+        }
+    }
+
+    private  class TestServiceDirectory implements ServiceDirectory {
+
+        private ClassToInstanceMap<Object> services = MutableClassToInstanceMap.create();
+
+        @Override
+        public <T> T get(Class<T> serviceClass) {
+            return services.getInstance(serviceClass);
+        }
+
+        /**
+         * Adds a new service to the directory.
+         *
+         * @param serviceClass service class
+         * @param service service instance
+         * @return self
+         */
+        public TestServiceDirectory add(Class serviceClass, Object service) {
+            services.putInstance(serviceClass, service);
+            return this;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminServiceAdapter.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminServiceAdapter.java
new file mode 100644
index 0000000..4fbed2f
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminServiceAdapter.java
@@ -0,0 +1,126 @@
+/*
+ * 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.onosproject.incubator.net.virtual;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TenantId;
+
+import java.util.Set;
+
+/**
+ * Test adapter for virtual network admin service.
+ */
+public class VirtualNetworkAdminServiceAdapter
+        extends VirtualNetworkServiceAdapter
+        implements VirtualNetworkAdminService {
+
+    @Override
+    public void registerTenantId(TenantId tenantId) {
+
+    }
+
+    @Override
+    public void unregisterTenantId(TenantId tenantId) {
+
+    }
+
+    @Override
+    public Set<TenantId> getTenantIds() {
+        return null;
+    }
+
+    @Override
+    public VirtualNetwork createVirtualNetwork(TenantId tenantId) {
+        return null;
+    }
+
+    @Override
+    public void removeVirtualNetwork(NetworkId networkId) {
+
+    }
+
+    @Override
+    public VirtualDevice createVirtualDevice(NetworkId networkId, DeviceId deviceId) {
+        return null;
+    }
+
+    @Override
+    public void removeVirtualDevice(NetworkId networkId, DeviceId deviceId) {
+
+    }
+
+    @Override
+    public VirtualHost createVirtualHost(NetworkId networkId, HostId hostId,
+                                         MacAddress mac, VlanId vlan,
+                                         HostLocation location, Set<IpAddress> ips) {
+        return null;
+    }
+
+    @Override
+    public void removeVirtualHost(NetworkId networkId, HostId hostId) {
+
+    }
+
+    @Override
+    public VirtualLink createVirtualLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
+        return null;
+    }
+
+    @Override
+    public void removeVirtualLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
+
+    }
+
+    @Override
+    public VirtualPort createVirtualPort(NetworkId networkId, DeviceId deviceId,
+                                         PortNumber portNumber, ConnectPoint realizedBy) {
+        return null;
+    }
+
+    @Override
+    public void bindVirtualPort(NetworkId networkId, DeviceId deviceId,
+                                PortNumber portNumber, ConnectPoint realizedBy) {
+
+    }
+
+    @Override
+    public void updatePortState(NetworkId networkId, DeviceId deviceId, PortNumber portNumber, boolean isEnabled) {
+
+    }
+
+    @Override
+    public void removeVirtualPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
+
+    }
+
+    @Override
+    public VirtualNetwork getVirtualNetwork(NetworkId networkId) {
+        return null;
+    }
+
+    @Override
+    public TenantId getTenantId(NetworkId networkId) {
+        return null;
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkServiceAdapter.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkServiceAdapter.java
new file mode 100644
index 0000000..9420d60
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkServiceAdapter.java
@@ -0,0 +1,84 @@
+/*
+ * 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.onosproject.incubator.net.virtual;
+
+import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.TenantId;
+
+import java.util.Set;
+
+/**
+ * Test adapter for virtual network service.
+ */
+public abstract class VirtualNetworkServiceAdapter implements VirtualNetworkService {
+    @Override
+    public void addListener(VirtualNetworkListener listener) {
+
+    }
+
+    @Override
+    public void removeListener(VirtualNetworkListener listener) {
+
+    }
+
+    @Override
+    public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
+        return null;
+    }
+
+    @Override
+    public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
+        return null;
+    }
+
+    @Override
+    public Set<VirtualHost> getVirtualHosts(NetworkId networkId) {
+        return null;
+    }
+
+    @Override
+    public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
+        return null;
+    }
+
+    @Override
+    public Set<VirtualPort> getVirtualPorts(NetworkId networkId, DeviceId deviceId) {
+        return null;
+    }
+
+    @Override
+    public Set<DeviceId> getPhysicalDevices(NetworkId networkId, DeviceId deviceId) {
+        return null;
+    }
+
+    @Override
+    public <T> T get(NetworkId networkId, Class<T> serviceClass) {
+        return null;
+    }
+
+    @Override
+    public ServiceDirectory getServiceDirectory() {
+        return null;
+    }
+
+    @Override
+    public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) {
+        return null;
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/TestCoreService.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/TestCoreService.java
new file mode 100644
index 0000000..80b74df
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/TestCoreService.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl;
+
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Core service test class.
+ */
+class TestCoreService extends CoreServiceAdapter {
+
+    @Override
+    public IdGenerator getIdGenerator(String topic) {
+        return new IdGenerator() {
+            private AtomicLong counter = new AtomicLong(0);
+
+            @Override
+            public long getNewId() {
+                return counter.getAndIncrement();
+            }
+        };
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManagerTest.java
new file mode 100644
index 0000000..63681e8
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManagerTest.java
@@ -0,0 +1,493 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl;
+
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestTools;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.event.Event;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.*;
+
+/**
+ * Junit tests for VirtualNetworkDeviceService.
+ */
+public class VirtualNetworkDeviceManagerTest extends VirtualNetworkTestUtil {
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService;
+    private TestServiceDirectory testDirectory;
+    private TestListener testListener = new TestListener();
+    private TestEventDispatcher dispatcher = new TestEventDispatcher();
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        coreService = new VirtualNetworkDeviceManagerTest.TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, dispatcher);
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+    }
+
+    /**
+     * Tests the getDevices(), getAvailableDevices(), getDeviceCount(), getDevice(), and isAvailable() methods.
+     */
+    @Test
+    public void testGetDevices() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice device1 = manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice device2 = manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getDevices() method
+        Iterator<Device> it = deviceService.getDevices().iterator();
+        assertEquals("The device set size did not match.", 2, Iterators.size(it));
+
+        // test the getAvailableDevices() method
+        Iterator<Device> it2 = deviceService.getAvailableDevices().iterator();
+        assertEquals("The device set size did not match.", 2, Iterators.size(it2));
+
+        // test the getDeviceCount() method
+        assertEquals("The device set size did not match.", 2, deviceService.getDeviceCount());
+
+        // test the getDevice() method
+        assertEquals("The expect device did not match.", device1,
+                     deviceService.getDevice(DID1));
+        assertNotEquals("The expect device should not have matched.", device1,
+                        deviceService.getDevice(DID2));
+
+        // test the isAvailable() method
+        assertTrue("The expect device availability did not match.",
+                   deviceService.isAvailable(DID1));
+        assertFalse("The expect device availability did not match.",
+                    deviceService.isAvailable(DID3));
+    }
+
+    /**
+     * Tests querying for a device using a null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDeviceByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getDevice() method with null device id value.
+        deviceService.getDevice(null);
+    }
+
+    /**
+     * Tests querying for a device using a null device type.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDeviceByNullType() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getDevices() method with null type value.
+        deviceService.getDevices(null);
+    }
+
+    /**
+     * Tests the isAvailable method using a null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsAvailableByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the isAvailable() method with null device id value.
+        deviceService.isAvailable(null);
+    }
+
+    /**
+     * Tests querying for a device and available devices by device type.
+     */
+    @Test
+    public void testGetDeviceType() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getDevices(Type) method.
+        Iterator<Device> it = deviceService.getDevices(Device.Type.VIRTUAL).iterator();
+        assertEquals("The device set size did not match.", 2, Iterators.size(it));
+        Iterator<Device> it2 = deviceService.getDevices(Device.Type.SWITCH).iterator();
+        assertEquals("The device set size did not match.", 0, Iterators.size(it2));
+
+        // test the getAvailableDevices(Type) method.
+        Iterator<Device> it3 = deviceService.getAvailableDevices(Device.Type.VIRTUAL).iterator();
+        assertEquals("The device set size did not match.", 2, Iterators.size(it3));
+    }
+
+    /**
+     * Tests querying the role of a device by null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetRoleByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getRole() method using a null device identifier
+        deviceService.getRole(null);
+    }
+
+    /**
+     * Tests querying the role of a device by device identifier.
+     */
+    @Test
+    public void testGetRole() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getRole() method
+        assertEquals("The expect device role did not match.", MastershipRole.MASTER,
+                     deviceService.getRole(DID1));
+    }
+
+    /**
+     * Tests querying the ports of a device by null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPortsByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getPorts() method using a null device identifier
+        deviceService.getPorts(null);
+    }
+
+    /**
+     * Tests querying the ports of a device by device identifier.
+     */
+    @Test
+    public void testGetPorts() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice = manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        ConnectPoint cp = new ConnectPoint(virtualDevice.id(), PortNumber.portNumber(1));
+
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice.id(), PortNumber.portNumber(1), cp);
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice.id(), PortNumber.portNumber(2), cp);
+
+        // test the getPorts() method
+        assertEquals("The port set size did not match.", 2,
+                     deviceService.getPorts(DID1).size());
+        assertEquals("The port set size did not match.", 0,
+                     deviceService.getPorts(DID2).size());
+    }
+
+    /**
+     * Tests querying the port of a device by device identifier and port number.
+     */
+    @Test
+    public void testGetPort() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice = manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        ConnectPoint cp = new ConnectPoint(virtualDevice.id(), PortNumber.portNumber(1));
+
+        VirtualPort virtualPort1 = manager.createVirtualPort(virtualNetwork.id(), virtualDevice.id(),
+                                                             PortNumber.portNumber(1), cp);
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice.id(), PortNumber.portNumber(2), cp);
+
+        // test the getPort() method
+        assertEquals("The port did not match as expected.", virtualPort1,
+                     deviceService.getPort(DID1, PortNumber.portNumber(1)));
+        assertNotEquals("The port did not match as expected.", virtualPort1,
+                        deviceService.getPort(DID1, PortNumber.portNumber(3)));
+    }
+
+    /**
+     * Tests querying the port statistics of a device by null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPortsStatisticsByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getPortStatistics() method using a null device identifier
+        deviceService.getPortStatistics(null);
+    }
+
+    /**
+     * Tests querying the port statistics of a device by device identifier.
+     */
+    @Test
+    public void testGetPortStatistics() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice = manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getPortStatistics() method
+        assertEquals("The port statistics set size did not match.", 0,
+                     deviceService.getPortStatistics(DID1).size());
+    }
+
+    /**
+     * Tests querying the port delta statistics of a device by null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPortsDeltaStatisticsByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getPortDeltaStatistics() method using a null device identifier
+        deviceService.getPortDeltaStatistics(null);
+    }
+
+    /**
+     * Tests querying the port delta statistics of a device by device identifier.
+     */
+    @Test
+    public void testGetPortDeltaStatistics() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice = manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // test the getPortDeltaStatistics() method
+        assertEquals("The port delta statistics set size did not match.", 0,
+                     deviceService.getPortDeltaStatistics(DID1).size());
+    }
+
+    /**
+     * Tests DeviceEvents received during virtual device/port addition and removal.
+     */
+    @Test
+    public void testDeviceEventsForAddRemovalDeviceAndPorts() throws TestUtils.TestUtilsException {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        // add virtual device before virtual device manager is created
+        VirtualDevice device1 = manager.createVirtualDevice(virtualNetwork.id(), VDID1);
+        validateEvents(); // no DeviceEvent expected
+
+        testDirectory.add(EventDeliveryService.class, dispatcher);
+        DeviceService deviceService = manager.get(virtualNetwork.id(), DeviceService.class);
+
+        // virtual device manager is created; register DeviceEvent listener
+        deviceService.addListener(testListener);
+
+        // list to keep track of expected event types
+        List<DeviceEvent.Type> expectedEventTypes = new ArrayList<>();
+
+        // add virtual device
+        VirtualDevice device2 = manager.createVirtualDevice(virtualNetwork.id(), VDID2);
+        expectedEventTypes.add(DeviceEvent.Type.DEVICE_ADDED);
+
+        ConnectPoint cp = new ConnectPoint(PHYDID1, PortNumber.portNumber(1));
+
+        // add 2 virtual ports
+        manager.createVirtualPort(virtualNetwork.id(),
+                                  device2.id(), PortNumber.portNumber(1), cp);
+        expectedEventTypes.add(DeviceEvent.Type.PORT_ADDED);
+        manager.createVirtualPort(virtualNetwork.id(),
+                                  device2.id(), PortNumber.portNumber(2), cp);
+        expectedEventTypes.add(DeviceEvent.Type.PORT_ADDED);
+
+        // verify virtual ports were added
+        Set<VirtualPort> virtualPorts = manager.getVirtualPorts(virtualNetwork.id(), device2.id());
+        assertNotNull("The virtual port set should not be null", virtualPorts);
+        assertEquals("The virtual port set size did not match.", 2, virtualPorts.size());
+        virtualPorts.forEach(vp -> assertFalse("Initial virtual port state should be disabled", vp.isEnabled()));
+
+        // verify change state of virtual port (disabled -> enabled)
+        manager.updatePortState(virtualNetwork.id(), device2.id(), PortNumber.portNumber(1), true);
+        Port changedPort = deviceService.getPort(device2.id(), PortNumber.portNumber(1));
+        assertNotNull("The changed virtual port should not be null", changedPort);
+        assertEquals("Virtual port state should be enabled", true, changedPort.isEnabled());
+        expectedEventTypes.add(DeviceEvent.Type.PORT_UPDATED);
+
+        // verify change state of virtual port (disabled -> disabled)
+        manager.updatePortState(virtualNetwork.id(), device2.id(), PortNumber.portNumber(2), false);
+        changedPort = deviceService.getPort(device2.id(), PortNumber.portNumber(2));
+        assertNotNull("The changed virtual port should not be null", changedPort);
+        assertEquals("Virtual port state should be disabled", false, changedPort.isEnabled());
+        // no VIRTUAL_PORT_UPDATED event is expected - the requested state (disabled) is same as previous state.
+
+        // remove 2 virtual ports
+        for (VirtualPort virtualPort : virtualPorts) {
+            manager.removeVirtualPort(virtualNetwork.id(),
+                                      (DeviceId) virtualPort.element().id(), virtualPort.number());
+            expectedEventTypes.add(DeviceEvent.Type.PORT_REMOVED);
+            // attempt to remove the same virtual port again - no DeviceEvent.Type.PORT_REMOVED expected.
+            manager.removeVirtualPort(virtualNetwork.id(),
+                                      (DeviceId) virtualPort.element().id(), virtualPort.number());
+        }
+
+        // verify virtual ports were removed
+        virtualPorts = manager.getVirtualPorts(virtualNetwork.id(), device2.id());
+        assertTrue("The virtual port set should be empty.", virtualPorts.isEmpty());
+
+        // Add/remove one virtual port again.
+        VirtualPort virtualPort =
+                manager.createVirtualPort(virtualNetwork.id(), device2.id(),
+                                                            PortNumber.portNumber(1), cp);
+        expectedEventTypes.add(DeviceEvent.Type.PORT_ADDED);
+
+        ConnectPoint newCp = new ConnectPoint(PHYDID3, PortNumber.portNumber(2));
+        manager.bindVirtualPort(virtualNetwork.id(), device2.id(),
+                                PortNumber.portNumber(1), newCp);
+        expectedEventTypes.add(DeviceEvent.Type.PORT_UPDATED);
+
+        manager.removeVirtualPort(virtualNetwork.id(),
+                                  (DeviceId) virtualPort.element().id(), virtualPort.number());
+        expectedEventTypes.add(DeviceEvent.Type.PORT_REMOVED);
+
+        // verify no virtual ports remain
+        virtualPorts = manager.getVirtualPorts(virtualNetwork.id(), device2.id());
+        assertTrue("The virtual port set should be empty.", virtualPorts.isEmpty());
+
+        // remove virtual device
+        manager.removeVirtualDevice(virtualNetwork.id(), device2.id());
+        expectedEventTypes.add(DeviceEvent.Type.DEVICE_REMOVED);
+
+        // Validate that the events were all received in the correct order.
+        validateEvents((Enum[]) expectedEventTypes.toArray(
+                new DeviceEvent.Type[expectedEventTypes.size()]));
+
+        // cleanup
+        deviceService.removeListener(testListener);
+    }
+
+    /**
+     * Core service test class.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+    }
+
+    /**
+     * Method to validate that the actual versus expected virtual network events were
+     * received correctly.
+     *
+     * @param types expected virtual network events.
+     */
+    private void validateEvents(Enum... types) {
+        TestTools.assertAfter(100, () -> {
+            int i = 0;
+            assertEquals("wrong events received", types.length, testListener.events.size());
+            for (Event event : testListener.events) {
+                assertEquals("incorrect event type", types[i], event.type());
+                i++;
+            }
+            testListener.events.clear();
+        });
+    }
+
+    /**
+     * Test listener class to receive device events.
+     */
+    private static class TestListener implements DeviceListener {
+
+        private List<DeviceEvent> events = Lists.newArrayList();
+
+        @Override
+        public void event(DeviceEvent event) {
+            events.add(event);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerTest.java
new file mode 100644
index 0000000..1def419
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerTest.java
@@ -0,0 +1,248 @@
+/*
+ * 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.onosproject.incubator.net.virtual.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.TestApplicationId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowRuleStore;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.TestStorageService;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Junit tests for VirtualNetworkFlowObjectiveManager.
+ */
+public class VirtualNetworkFlowObjectiveManagerTest
+        extends VirtualNetworkTestUtil {
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private ServiceDirectory testDirectory;
+    protected SimpleVirtualFlowObjectiveStore flowObjectiveStore;
+
+    private VirtualProviderManager providerRegistryService;
+    private EventDeliveryService eventDeliveryService;
+
+    private ApplicationId appId;
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private FlowObjectiveService service1;
+    private FlowObjectiveService service2;
+
+    //FIXME: referring flowrule service, store, and provider shouldn't be here
+    private VirtualFlowRuleProvider flowRuleProvider = new TestProvider();
+    private SimpleVirtualFlowRuleStore flowRuleStore;
+    protected StorageService storageService = new TestStorageService();
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", storageService);
+        virtualNetworkManagerStore.activate();
+
+        flowObjectiveStore = new SimpleVirtualFlowObjectiveStore();
+        TestUtils.setField(flowObjectiveStore, "storageService", storageService);
+        flowObjectiveStore.activate();
+        flowRuleStore = new SimpleVirtualFlowRuleStore();
+        flowRuleStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        TestUtils.setField(manager, "coreService", coreService);
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(flowRuleProvider);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+
+        appId = new TestApplicationId("FlowRuleManagerTest");
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(VirtualNetworkFlowRuleStore.class, flowRuleStore)
+                .add(VirtualNetworkFlowObjectiveStore.class, flowObjectiveStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        vnet1 = setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = setupVirtualNetworkTopology(manager, TID2);
+
+        service1 = new VirtualNetworkFlowObjectiveManager(manager, vnet1.id());
+        service2 = new VirtualNetworkFlowObjectiveManager(manager, vnet2.id());
+    }
+
+    @After
+    public void tearDownTest() {
+        manager.deactivate();
+        virtualNetworkManagerStore.deactivate();
+    }
+
+    /**
+     * Tests adding a forwarding objective.
+     */
+    @Test
+    public void forwardingObjective() {
+        TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        ForwardingObjective forward =
+                DefaultForwardingObjective.builder()
+                        .fromApp(NetTestTools.APP_ID)
+                        .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                        .withSelector(selector)
+                        .withTreatment(treatment)
+                        .makePermanent()
+                        .add(new ObjectiveContext() {
+                            @Override
+                            public void onSuccess(Objective objective) {
+                                assertEquals("1 flowrule entry expected",
+                                             1, flowRuleStore.getFlowRuleCount(vnet1.id()));
+                                assertEquals("0 flowrule entry expected",
+                                             0, flowRuleStore.getFlowRuleCount(vnet2.id()));
+                            }
+                        });
+
+        service1.forward(VDID1, forward);
+    }
+
+    /**
+     * Tests adding a next objective.
+     */
+    @Test
+    public void nextObjective() {
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        NextObjective nextObjective = DefaultNextObjective.builder()
+                .withId(service1.allocateNextId())
+                .fromApp(NetTestTools.APP_ID)
+                .addTreatment(treatment)
+                .withType(NextObjective.Type.BROADCAST)
+                .makePermanent()
+                .add(new ObjectiveContext() {
+                    @Override
+                    public void onSuccess(Objective objective) {
+                        assertEquals("1 next map entry expected",
+                                     1, service1.getNextMappings().size());
+                        assertEquals("0 next map entry expected",
+                                     0, service2.getNextMappings().size());
+                    }
+                });
+
+        service1.next(VDID1, nextObjective);
+    }
+
+    /**
+     * Tests adding a filtering objective.
+     */
+    @Test
+    public void filteringObjective() {
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        FilteringObjective filter =
+                DefaultFilteringObjective.builder()
+                        .fromApp(NetTestTools.APP_ID)
+                        .withMeta(treatment)
+                        .makePermanent()
+                        .deny()
+                        .addCondition(Criteria.matchEthType(12))
+                        .add(new ObjectiveContext() {
+                            @Override
+                            public void onSuccess(Objective objective) {
+                                assertEquals("1 flowrule entry expected",
+                                             1,
+                                             flowRuleStore.getFlowRuleCount(vnet1.id()));
+                                assertEquals("0 flowrule entry expected",
+                                             0,
+                                             flowRuleStore.getFlowRuleCount(vnet2.id()));
+
+                            }
+                        });
+
+        service1.filter(VDID1, filter);
+    }
+
+    //TODO: More test cases for filter, forward, and next
+
+    private class TestProvider extends AbstractVirtualProvider
+            implements VirtualFlowRuleProvider {
+
+        protected TestProvider() {
+            super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
+        }
+
+        @Override
+        public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
+
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerWithDistStoreTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerWithDistStoreTest.java
new file mode 100644
index 0000000..78ed454
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerWithDistStoreTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.onosproject.incubator.net.virtual.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.onlab.junit.TestUtils;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualFlowObjectiveStore;
+
+/**
+ * Junit tests for VirtualNetworkFlowObjectiveManager using
+ * DistributedVirtualFlowObjectiveStore.  This test class extends
+ * VirtualNetworkFlowObjectiveManagerTest - all the tests defined in
+ * VirtualNetworkFlowObjectiveManagerTest will run using
+ * DistributedVirtualFlowObjectiveStore.
+ */
+public class VirtualNetworkFlowObjectiveManagerWithDistStoreTest
+        extends VirtualNetworkFlowObjectiveManagerTest {
+
+    private static final String STORE_FIELDNAME_STORAGESERVICE = "storageService";
+
+    private DistributedVirtualFlowObjectiveStore distStore;
+
+    @Before
+    public void setUp() throws Exception {
+        setupDistFlowObjectiveStore();
+        super.setUp();
+    }
+
+    private void setupDistFlowObjectiveStore() throws TestUtils.TestUtilsException {
+        distStore = new DistributedVirtualFlowObjectiveStore();
+        TestUtils.setField(distStore, STORE_FIELDNAME_STORAGESERVICE, storageService);
+
+        distStore.activate();
+        flowObjectiveStore = distStore; // super.setUp() will cause Distributed store to be used.
+    }
+
+    @After
+    public void tearDown() {
+        distStore.deactivate();
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java
new file mode 100644
index 0000000..037b67f
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java
@@ -0,0 +1,533 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.TestApplicationId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowRuleStore;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleListener;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.StoredFlowEntry;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+import static org.onosproject.net.flow.FlowRuleEvent.Type.*;
+
+public class VirtualNetworkFlowRuleManagerTest extends VirtualNetworkTestUtil {
+    private static final int TIMEOUT = 10;
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private ServiceDirectory testDirectory;
+    private VirtualNetworkFlowRuleStore flowRuleStore;
+    private VirtualProviderManager providerRegistryService;
+
+    private EventDeliveryService eventDeliveryService;
+
+    private VirtualNetworkFlowRuleManager vnetFlowRuleService1;
+    private VirtualNetworkFlowRuleManager vnetFlowRuleService2;
+
+    private VirtualFlowRuleProvider provider = new TestProvider();
+    private VirtualFlowRuleProviderService providerService1;
+    private VirtualFlowRuleProviderService providerService2;
+
+    protected TestFlowRuleListener listener1 = new TestFlowRuleListener();
+    protected TestFlowRuleListener listener2 = new TestFlowRuleListener();
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private ApplicationId appId;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        flowRuleStore = new SimpleVirtualFlowRuleStore();
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(provider);
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        TestUtils.setField(manager, "coreService", coreService);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+
+        appId = new TestApplicationId("FlowRuleManagerTest");
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(VirtualNetworkFlowRuleStore.class, flowRuleStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        vnet1 = setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = setupVirtualNetworkTopology(manager, TID2);
+
+        vnetFlowRuleService1 = new VirtualNetworkFlowRuleManager(manager, vnet1.id());
+        vnetFlowRuleService2 = new VirtualNetworkFlowRuleManager(manager, vnet2.id());
+        vnetFlowRuleService1.addListener(listener1);
+        vnetFlowRuleService2.addListener(listener2);
+
+        vnetFlowRuleService1.operationsService = MoreExecutors.newDirectExecutorService();
+        vnetFlowRuleService2.operationsService = MoreExecutors.newDirectExecutorService();
+        vnetFlowRuleService1.deviceInstallers = MoreExecutors.newDirectExecutorService();
+        vnetFlowRuleService2.deviceInstallers = MoreExecutors.newDirectExecutorService();
+
+        providerService1 = (VirtualFlowRuleProviderService)
+                providerRegistryService.getProviderService(vnet1.id(), VirtualFlowRuleProvider.class);
+        providerService2 = (VirtualFlowRuleProviderService)
+                providerRegistryService.getProviderService(vnet2.id(), VirtualFlowRuleProvider.class);
+    }
+
+    @After
+    public void tearDown() {
+        manager.deactivate();
+        virtualNetworkManagerStore.deactivate();
+    }
+
+    private FlowRule flowRule(int tsval, int trval) {
+        return flowRule(VDID1, tsval, trval);
+    }
+
+    private FlowRule flowRule(DeviceId did, int tsval, int trval) {
+        TestSelector ts = new TestSelector(tsval);
+        TestTreatment tr = new TestTreatment(trval);
+        return DefaultFlowRule.builder()
+                .forDevice(did)
+                .withSelector(ts)
+                .withTreatment(tr)
+                .withPriority(10)
+                .fromApp(appId)
+                .makeTemporary(TIMEOUT)
+                .build();
+    }
+
+    private FlowRule addFlowRule(int hval) {
+        FlowRule rule = flowRule(hval, hval);
+        vnetFlowRuleService1.applyFlowRules(rule);
+
+        assertNotNull("rule should be found", vnetFlowRuleService1.getFlowEntries(VDID1));
+        return rule;
+    }
+
+    private int flowCount(FlowRuleService service) {
+        List<FlowEntry> entries = Lists.newArrayList();
+        service.getFlowEntries(VDID1).forEach(entries::add);
+        return entries.size();
+    }
+
+    @Test
+    public void getFlowEntries() {
+        assertTrue("store should be empty",
+                   Sets.newHashSet(vnetFlowRuleService1.getFlowEntries(VDID1)).isEmpty());
+        assertTrue("store should be empty",
+                   Sets.newHashSet(vnetFlowRuleService2.getFlowEntries(VDID1)).isEmpty());
+
+        FlowRule f1 = addFlowRule(1);
+        FlowRule f2 = addFlowRule(2);
+
+        FlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+
+        assertEquals("2 rules should exist", 2, flowCount(vnetFlowRuleService1));
+        assertEquals("0 rules should exist", 0, flowCount(vnetFlowRuleService2));
+
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2));
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
+                       RULE_ADDED, RULE_ADDED);
+
+        addFlowRule(1);
+        assertEquals("should still be 2 rules", 2, flowCount(vnetFlowRuleService1));
+        System.err.println("events :" + listener1.events);
+        assertEquals("0 rules should exist", 0, flowCount(vnetFlowRuleService2));
+
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1));
+        validateEvents(listener1, RULE_UPDATED, RULE_UPDATED);
+    }
+
+    @Test
+    public void applyFlowRules() {
+        FlowRule r1 = flowRule(1, 1);
+        FlowRule r2 = flowRule(2, 2);
+        FlowRule r3 = flowRule(3, 3);
+
+        assertTrue("store should be empty",
+                   Sets.newHashSet(vnetFlowRuleService1.getFlowEntries(DID1)).isEmpty());
+        vnetFlowRuleService1.applyFlowRules(r1, r2, r3);
+        assertEquals("3 rules should exist", 3, flowCount(vnetFlowRuleService1));
+        assertTrue("Entries should be pending add.",
+                   validateState(ImmutableMap.of(
+                           r1, FlowEntry.FlowEntryState.PENDING_ADD,
+                           r2, FlowEntry.FlowEntryState.PENDING_ADD,
+                           r3, FlowEntry.FlowEntryState.PENDING_ADD)));
+    }
+
+    @Test
+    public void purgeFlowRules() {
+        FlowRule f1 = addFlowRule(1);
+        FlowRule f2 = addFlowRule(2);
+        FlowRule f3 = addFlowRule(3);
+        assertEquals("3 rules should exist", 3, flowCount(vnetFlowRuleService1));
+        FlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+        FlowEntry fe3 = new DefaultFlowEntry(f3);
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2, fe3));
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
+                       RULE_ADDED, RULE_ADDED, RULE_ADDED);
+        vnetFlowRuleService1.purgeFlowRules(VDID1);
+        assertEquals("0 rule should exist", 0, flowCount(vnetFlowRuleService1));
+    }
+
+    @Test
+    public void removeFlowRules() {
+        FlowRule f1 = addFlowRule(1);
+        FlowRule f2 = addFlowRule(2);
+        FlowRule f3 = addFlowRule(3);
+        assertEquals("3 rules should exist", 3, flowCount(vnetFlowRuleService1));
+
+        FlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+        FlowEntry fe3 = new DefaultFlowEntry(f3);
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2, fe3));
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
+                       RULE_ADDED, RULE_ADDED, RULE_ADDED);
+
+        vnetFlowRuleService1.removeFlowRules(f1, f2);
+        //removing from north, so no events generated
+        validateEvents(listener1, RULE_REMOVE_REQUESTED, RULE_REMOVE_REQUESTED);
+        assertEquals("3 rule should exist", 3, flowCount(vnetFlowRuleService1));
+        assertTrue("Entries should be pending remove.",
+                   validateState(ImmutableMap.of(
+                           f1, FlowEntry.FlowEntryState.PENDING_REMOVE,
+                           f2, FlowEntry.FlowEntryState.PENDING_REMOVE,
+                           f3, FlowEntry.FlowEntryState.ADDED)));
+
+        vnetFlowRuleService1.removeFlowRules(f1);
+        assertEquals("3 rule should still exist", 3, flowCount(vnetFlowRuleService1));
+    }
+
+    @Test
+    public void flowRemoved() {
+        FlowRule f1 = addFlowRule(1);
+        FlowRule f2 = addFlowRule(2);
+        StoredFlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2));
+        vnetFlowRuleService1.removeFlowRules(f1);
+
+        //FIXME modification of "stored" flow entry outside of store
+        fe1.setState(FlowEntry.FlowEntryState.REMOVED);
+
+        providerService1.flowRemoved(fe1);
+
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED,
+                       RULE_ADDED, RULE_REMOVE_REQUESTED, RULE_REMOVED);
+
+        providerService1.flowRemoved(fe1);
+        validateEvents(listener1);
+
+        FlowRule f3 = flowRule(3, 3);
+        FlowEntry fe3 = new DefaultFlowEntry(f3);
+        vnetFlowRuleService1.applyFlowRules(f3);
+
+        providerService1.pushFlowMetrics(VDID1, Collections.singletonList(fe3));
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADDED, RULE_UPDATED);
+
+        providerService1.flowRemoved(fe3);
+        validateEvents(listener1);
+    }
+
+    @Test
+    public void extraneousFlow() {
+        FlowRule f1 = flowRule(1, 1);
+        FlowRule f2 = flowRule(2, 2);
+        FlowRule f3 = flowRule(3, 3);
+        vnetFlowRuleService1.applyFlowRules(f1, f2);
+
+        FlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+        FlowEntry fe3 = new DefaultFlowEntry(f3);
+
+
+        providerService1.pushFlowMetrics(VDID1, Lists.newArrayList(fe1, fe2, fe3));
+
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
+                       RULE_ADDED, RULE_ADDED);
+    }
+
+    /*
+     * Tests whether a rule that was marked for removal but no flowRemoved was received
+     * is indeed removed at the next stats update.
+     */
+    @Test
+    public void flowMissingRemove() {
+        FlowRule f1 = flowRule(1, 1);
+        FlowRule f2 = flowRule(2, 2);
+        FlowRule f3 = flowRule(3, 3);
+
+        FlowEntry fe1 = new DefaultFlowEntry(f1);
+        FlowEntry fe2 = new DefaultFlowEntry(f2);
+        vnetFlowRuleService1.applyFlowRules(f1, f2, f3);
+
+        vnetFlowRuleService1.removeFlowRules(f3);
+
+        providerService1.pushFlowMetrics(VDID1, Lists.newArrayList(fe1, fe2));
+
+        validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
+                       RULE_REMOVE_REQUESTED, RULE_ADDED, RULE_ADDED, RULE_REMOVED);
+    }
+
+    @Test
+    public void removeByAppId() {
+        FlowRule f1 = flowRule(1, 1);
+        FlowRule f2 = flowRule(2, 2);
+        vnetFlowRuleService1.applyFlowRules(f1, f2);
+
+        vnetFlowRuleService1.removeFlowRulesById(appId);
+
+        //only check that we are in pending remove. Events and actual remove state will
+        // be set by flowRemoved call.
+        validateState(ImmutableMap.of(
+                f1, FlowEntry.FlowEntryState.PENDING_REMOVE,
+                f2, FlowEntry.FlowEntryState.PENDING_REMOVE));
+    }
+
+    //TODO:Tests for fallback
+
+    private boolean validateState(Map<FlowRule, FlowEntry.FlowEntryState> expected) {
+        Map<FlowRule, FlowEntry.FlowEntryState> expectedToCheck = new HashMap<>(expected);
+        Iterable<FlowEntry> rules = vnetFlowRuleService1.getFlowEntries(VDID1);
+        for (FlowEntry f : rules) {
+            assertTrue("Unexpected FlowRule " + f, expectedToCheck.containsKey(f));
+            assertEquals("FlowEntry" + f, expectedToCheck.get(f), f.state());
+            expectedToCheck.remove(f);
+        }
+        assertEquals(Collections.emptySet(), expectedToCheck.entrySet());
+        return true;
+    }
+
+    private class TestSelector implements TrafficSelector {
+
+        //for controlling hashcode uniqueness;
+        private final int testval;
+
+        public TestSelector(int val) {
+            testval = val;
+        }
+
+        @Override
+        public Set<Criterion> criteria() {
+            return Collections.emptySet();
+        }
+
+        @Override
+        public Criterion getCriterion(
+                org.onosproject.net.flow.criteria.Criterion.Type type) {
+            return null;
+        }
+
+        @Override
+        public int hashCode() {
+            return testval;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof TestSelector) {
+                return this.testval == ((TestSelector) o).testval;
+            }
+            return false;
+        }
+    }
+
+    private class TestTreatment implements TrafficTreatment {
+
+        //for controlling hashcode uniqueness;
+        private final int testval;
+
+        public TestTreatment(int val) {
+            testval = val;
+        }
+
+        @Override
+        public List<Instruction> deferred() {
+            return null;
+        }
+
+        @Override
+        public List<Instruction> immediate() {
+            return null;
+        }
+
+        @Override
+        public List<Instruction> allInstructions() {
+            return null;
+        }
+
+        @Override
+        public Instructions.TableTypeTransition tableTransition() {
+            return null;
+        }
+
+        @Override
+        public boolean clearedDeferred() {
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return testval;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof TestTreatment) {
+                return this.testval == ((TestTreatment) o).testval;
+            }
+            return false;
+        }
+
+        @Override
+        public Instructions.MetadataInstruction writeMetadata() {
+            return null;
+        }
+
+        @Override
+        public Instructions.StatTriggerInstruction statTrigger() {
+            return null;
+        }
+
+        @Override
+        public Instructions.MeterInstruction metered() {
+            return null;
+        }
+
+        @Override
+        public Set<Instructions.MeterInstruction> meters() {
+            return Sets.newHashSet();
+        }
+    }
+
+    private void validateEvents(TestFlowRuleListener listener, FlowRuleEvent.Type... events) {
+        if (events == null) {
+            assertTrue("events generated", listener.events.isEmpty());
+        }
+
+        int i = 0;
+        System.err.println("events :" + listener.events);
+        for (FlowRuleEvent e : listener.events) {
+            assertEquals("unexpected event", events[i], e.type());
+            i++;
+        }
+
+        assertEquals("mispredicted number of events",
+                     events.length, listener.events.size());
+
+        listener.events.clear();
+    }
+
+    private class TestFlowRuleListener implements FlowRuleListener {
+
+        public final List<FlowRuleEvent> events = new ArrayList<>();
+
+        @Override
+        public void event(FlowRuleEvent event) {
+            events.add(event);
+        }
+    }
+
+    private class TestProvider extends AbstractVirtualProvider
+            implements VirtualFlowRuleProvider {
+
+        protected TestProvider() {
+            super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
+        }
+
+        @Override
+        public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
+
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkGroupManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkGroupManagerTest.java
new file mode 100644
index 0000000..7aa0d9c
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkGroupManagerTest.java
@@ -0,0 +1,702 @@
+/*
+ * 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.onosproject.incubator.net.virtual.impl;
+
+import com.google.common.collect.Iterables;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onosproject.TestApplicationId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.GroupId;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkGroupStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualGroupProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualGroupProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualGroupStore;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroup;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupEvent;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupListener;
+import org.onosproject.net.group.GroupOperation;
+import org.onosproject.net.group.GroupOperations;
+import org.onosproject.net.group.StoredGroupEntry;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.*;
+import static org.onosproject.incubator.net.virtual.impl.VirtualNetworkTestUtil.*;
+import static org.onosproject.net.NetTestTools.injectEventDispatcher;
+
+/**
+ * Test codifying the virtual group service & group provider service contracts.
+ */
+public class VirtualNetworkGroupManagerTest {
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private ServiceDirectory testDirectory;
+    private VirtualProviderManager providerRegistryService;
+
+    private EventDeliveryService eventDeliveryService;
+
+    private VirtualNetworkGroupManager groupManager1;
+    private VirtualNetworkGroupManager groupManager2;
+
+    private VirtualNetworkGroupStore groupStore;
+
+    private TestGroupProvider provider = new TestGroupProvider();
+    private VirtualGroupProviderService providerService1;
+    private VirtualGroupProviderService providerService2;
+
+    protected TestGroupListener listener1 = new TestGroupListener();
+    protected TestGroupListener listener2 = new TestGroupListener();
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private ApplicationId appId;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        groupStore = new SimpleVirtualGroupStore();
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(provider);
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        TestUtils.setField(manager, "coreService", coreService);
+
+        eventDeliveryService = new TestEventDispatcher();
+        injectEventDispatcher(manager, eventDeliveryService);
+
+        appId = new TestApplicationId("VirtualGroupManagerTest");
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(VirtualNetworkGroupStore.class, groupStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        vnet1 = setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = setupVirtualNetworkTopology(manager, TID2);
+
+        groupManager1 = new VirtualNetworkGroupManager(manager, vnet1.id());
+        groupManager2 = new VirtualNetworkGroupManager(manager, vnet2.id());
+        groupManager1.addListener(listener1);
+        groupManager2.addListener(listener2);
+
+        providerService1 = (VirtualGroupProviderService)
+                providerRegistryService.getProviderService(vnet1.id(),
+                                                           VirtualGroupProvider.class);
+        providerService2 = (VirtualGroupProviderService)
+                providerRegistryService.getProviderService(vnet2.id(),
+                                                           VirtualGroupProvider.class);
+    }
+
+    @After
+    public void tearDown() {
+        providerRegistryService.unregisterProvider(provider);
+        assertFalse("provider should not be registered",
+                    providerRegistryService.getProviders().contains(provider.id()));
+        groupManager1.removeListener(listener1);
+        groupManager2.removeListener(listener2);
+
+        manager.deactivate();
+        virtualNetworkManagerStore.deactivate();
+    }
+
+    /**
+     * Tests group creation before the device group AUDIT completes.
+     */
+    @Test
+    public void testGroupServiceBasics() {
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests initial device group AUDIT process.
+     */
+    @Test
+    public void testGroupServiceInitialAudit() {
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+        // Test initial group audit process
+        testInitialAuditWithPendingGroupRequests(vnet1.id(), VDID1);
+        testInitialAuditWithPendingGroupRequests(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests deletion process of any extraneous groups.
+     */
+    @Test
+    public void testGroupServiceAuditExtraneous() {
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+
+        // Test audit with extraneous and missing groups
+        testAuditWithExtraneousMissingGroups(vnet1.id(), VDID1);
+        testAuditWithExtraneousMissingGroups(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests re-apply process of any missing groups tests execution of
+     * any pending group creation request after the device group AUDIT completes
+     * and tests event notifications after receiving confirmation for any
+     * operations from data plane.
+     */
+    @Test
+    public void testGroupServiceAuditConfirmed() {
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+
+        // Test audit with extraneous and missing groups
+        testAuditWithExtraneousMissingGroups(vnet1.id(), VDID1);
+        testAuditWithExtraneousMissingGroups(vnet2.id(), VDID1);
+
+        // Test audit with confirmed groups
+        testAuditWithConfirmedGroups(vnet1.id(), VDID1);
+        testAuditWithConfirmedGroups(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests group Purge Operation.
+     */
+    @Test
+    public void testPurgeGroups() {
+        // Tests for virtual network 1
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+        testAuditWithExtraneousMissingGroups(vnet1.id(), VDID1);
+        // Test group add bucket operations
+        testAddBuckets(vnet1.id(), VDID1);
+        // Test group Purge operations
+        testPurgeGroupEntry(vnet1.id(), VDID1);
+
+        // Tests for virtual network 2
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+        testAuditWithExtraneousMissingGroups(vnet2.id(), VDID1);
+        // Test group add bucket operations
+        testAddBuckets(vnet2.id(), VDID1);
+        // Test group Purge operations
+        testPurgeGroupEntry(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests group bucket modifications (additions and deletions) and
+     * Tests group deletion.
+     */
+    @Test
+    public void testGroupServiceBuckets() {
+        // Tests for virtual network 1
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID1);
+
+        testAuditWithExtraneousMissingGroups(vnet1.id(), VDID1);
+        // Test group add bucket operations
+        testAddBuckets(vnet1.id(), VDID1);
+
+        // Test group remove bucket operations
+        testRemoveBuckets(vnet1.id(), VDID1);
+
+        // Test group remove operations
+        testRemoveGroup(vnet1.id(), VDID1);
+
+        // Tests for virtual network 2
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet2.id(), VDID1);
+
+        testAuditWithExtraneousMissingGroups(vnet2.id(), VDID1);
+        // Test group add bucket operations
+        testAddBuckets(vnet2.id(), VDID1);
+
+        // Test group remove bucket operations
+        testRemoveBuckets(vnet2.id(), VDID1);
+
+        // Test group remove operations
+        testRemoveGroup(vnet2.id(), VDID1);
+    }
+
+    /**
+     * Tests group creation before the device group AUDIT completes with fallback
+     * provider.
+     */
+    @Test
+    public void testGroupServiceFallbackBasics() {
+        // Test Group creation before AUDIT process
+        testGroupCreationBeforeAudit(vnet1.id(), VDID2);
+        testGroupCreationBeforeAudit(vnet2.id(), VDID2);
+    }
+
+    // Test Group creation before AUDIT process
+    private void testGroupCreationBeforeAudit(NetworkId networkId, DeviceId deviceId) {
+        PortNumber[] ports1 = {PortNumber.portNumber(31),
+                PortNumber.portNumber(32)};
+        PortNumber[] ports2 = {PortNumber.portNumber(41),
+                PortNumber.portNumber(42)};
+        GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
+        List<GroupBucket> buckets = new ArrayList<>();
+        List<PortNumber> outPorts = new ArrayList<>();
+        outPorts.addAll(Arrays.asList(ports1));
+        outPorts.addAll(Arrays.asList(ports2));
+        for (PortNumber portNumber : outPorts) {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(portNumber)
+                    .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
+                    .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                    .pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(106));
+            buckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+        }
+        GroupBuckets groupBuckets = new GroupBuckets(buckets);
+        GroupDescription newGroupDesc = new DefaultGroupDescription(deviceId,
+                                                                    Group.Type.SELECT,
+                                                                    groupBuckets,
+                                                                    key,
+                                                                    null,
+                                                                    appId);
+        VirtualNetworkGroupManager groupManager;
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+        } else {
+            groupManager = groupManager2;
+        }
+
+        groupManager.addGroup(newGroupDesc);
+        assertEquals(null, groupManager.getGroup(deviceId, key));
+        assertEquals(0, Iterables.size(groupManager.getGroups(deviceId, appId)));
+    }
+
+
+    // Test initial AUDIT process with pending group requests
+    private void testInitialAuditWithPendingGroupRequests(NetworkId networkId,
+                                                          DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+        }
+
+        PortNumber[] ports1 = {PortNumber.portNumber(31),
+                PortNumber.portNumber(32)};
+        PortNumber[] ports2 = {PortNumber.portNumber(41),
+                PortNumber.portNumber(42)};
+        GroupId gId1 = new GroupId(1);
+        Group group1 = createSouthboundGroupEntry(gId1,
+                                                  Arrays.asList(ports1),
+                                                  0, deviceId);
+        GroupId gId2 = new GroupId(2);
+        // Non zero reference count will make the group manager to queue
+        // the extraneous groups until reference count is zero.
+        Group group2 = createSouthboundGroupEntry(gId2,
+                                                  Arrays.asList(ports2),
+                                                  2, deviceId);
+        List<Group> groupEntries = Arrays.asList(group1, group2);
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        // First group metrics would trigger the device audit completion
+        // post which all pending group requests are also executed.
+        GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
+        Group createdGroup = groupManager.getGroup(deviceId, key);
+        int createdGroupId = createdGroup.id().id();
+        assertNotEquals(gId1.id().intValue(), createdGroupId);
+        assertNotEquals(gId2.id().intValue(), createdGroupId);
+
+        List<GroupOperation> expectedGroupOps = Arrays.asList(
+                GroupOperation.createDeleteGroupOperation(gId1,
+                                                          Group.Type.SELECT),
+                GroupOperation.createAddGroupOperation(
+                        createdGroup.id(),
+                        Group.Type.SELECT,
+                        createdGroup.buckets()));
+        if (deviceId.equals(VDID1)) {
+            provider.validate(networkId, deviceId, expectedGroupOps);
+        }
+    }
+
+    // Test AUDIT process with extraneous groups and missing groups
+    private void testAuditWithExtraneousMissingGroups(NetworkId networkId,
+                                                      DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+        }
+
+        PortNumber[] ports1 = {PortNumber.portNumber(31),
+                PortNumber.portNumber(32)};
+        PortNumber[] ports2 = {PortNumber.portNumber(41),
+                PortNumber.portNumber(42)};
+        GroupId gId1 = new GroupId(1);
+        Group group1 = createSouthboundGroupEntry(gId1,
+                                                  Arrays.asList(ports1),
+                                                  0, deviceId);
+        GroupId gId2 = new GroupId(2);
+        Group group2 = createSouthboundGroupEntry(gId2,
+                                                  Arrays.asList(ports2),
+                                                  0, deviceId);
+        List<Group> groupEntries = Arrays.asList(group1, group2);
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
+        Group createdGroup = groupManager.getGroup(deviceId, key);
+        List<GroupOperation> expectedGroupOps = Arrays.asList(
+                GroupOperation.createDeleteGroupOperation(gId1,
+                                                          Group.Type.SELECT),
+                GroupOperation.createDeleteGroupOperation(gId2,
+                                                          Group.Type.SELECT),
+                GroupOperation.createAddGroupOperation(createdGroup.id(),
+                                                       Group.Type.SELECT,
+                                                       createdGroup.buckets()));
+        if (deviceId.equals(VDID1)) {
+            provider.validate(networkId, deviceId, expectedGroupOps);
+        }
+    }
+
+    // Test AUDIT with confirmed groups
+    private void testAuditWithConfirmedGroups(NetworkId networkId,
+                                              DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        TestGroupListener listener;
+
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+            listener = listener1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+            listener = listener2;
+        }
+
+        GroupKey key = new DefaultGroupKey("group1BeforeAudit".getBytes());
+        Group createdGroup = groupManager.getGroup(deviceId, key);
+        createdGroup = new DefaultGroup(createdGroup.id(),
+                                        deviceId,
+                                        Group.Type.SELECT,
+                                        createdGroup.buckets());
+        List<Group> groupEntries = Collections.singletonList(createdGroup);
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        listener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_ADDED));
+    }
+
+    private Group createSouthboundGroupEntry(GroupId gId,
+                                             List<PortNumber> ports,
+                                             long referenceCount, DeviceId deviceId) {
+        List<PortNumber> outPorts = new ArrayList<>();
+        outPorts.addAll(ports);
+
+        List<GroupBucket> buckets = new ArrayList<>();
+        for (PortNumber portNumber : outPorts) {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(portNumber)
+                    .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
+                    .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                    .pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(106));
+            buckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+        }
+        GroupBuckets groupBuckets = new GroupBuckets(buckets);
+        StoredGroupEntry group = new DefaultGroup(
+                gId, deviceId, Group.Type.SELECT, groupBuckets);
+        group.setReferenceCount(referenceCount);
+        return group;
+    }
+
+    // Test group add bucket operations
+    private void testAddBuckets(NetworkId networkId, DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        TestGroupListener listener;
+
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+            listener = listener1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+            listener = listener2;
+        }
+
+        GroupKey addKey = new DefaultGroupKey("group1AddBuckets".getBytes());
+
+        GroupKey prevKey = new DefaultGroupKey("group1BeforeAudit".getBytes());
+        Group createdGroup = groupManager.getGroup(deviceId, prevKey);
+        List<GroupBucket> buckets = new ArrayList<>();
+        buckets.addAll(createdGroup.buckets().buckets());
+
+        PortNumber[] addPorts = {PortNumber.portNumber(51),
+                PortNumber.portNumber(52)};
+        List<PortNumber> outPorts;
+        outPorts = new ArrayList<>();
+        outPorts.addAll(Arrays.asList(addPorts));
+        List<GroupBucket> addBuckets;
+        addBuckets = new ArrayList<>();
+        for (PortNumber portNumber : outPorts) {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(portNumber)
+                    .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
+                    .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                    .pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(106));
+            addBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+            buckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+        }
+        GroupBuckets groupAddBuckets = new GroupBuckets(addBuckets);
+        groupManager.addBucketsToGroup(deviceId,
+                                       prevKey,
+                                       groupAddBuckets,
+                                       addKey,
+                                       appId);
+        GroupBuckets updatedBuckets = new GroupBuckets(buckets);
+        List<GroupOperation> expectedGroupOps = Collections.singletonList(
+                GroupOperation.createModifyGroupOperation(createdGroup.id(),
+                                                          Group.Type.SELECT,
+                                                          updatedBuckets));
+        if (deviceId.equals(VDID1)) {
+            provider.validate(networkId, deviceId, expectedGroupOps);
+        }
+
+        Group existingGroup = groupManager.getGroup(deviceId, addKey);
+        List<Group> groupEntries = Collections.singletonList(existingGroup);
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        listener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
+    }
+
+    // Test purge group entry operations
+    private void testPurgeGroupEntry(NetworkId networkId, DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+        } else {
+            groupManager = groupManager2;
+        }
+
+        assertEquals(1, Iterables.size(groupManager.getGroups(deviceId, appId)));
+        groupManager.purgeGroupEntries(deviceId);
+        assertEquals(0, Iterables.size(groupManager.getGroups(deviceId, appId)));
+    }
+
+    // Test group remove bucket operations
+    private void testRemoveBuckets(NetworkId networkId, DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        TestGroupListener listener;
+
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+            listener = listener1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+            listener = listener2;
+        }
+
+        GroupKey removeKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
+
+        GroupKey prevKey = new DefaultGroupKey("group1AddBuckets".getBytes());
+        Group createdGroup = groupManager.getGroup(deviceId, prevKey);
+        List<GroupBucket> buckets = new ArrayList<>();
+        buckets.addAll(createdGroup.buckets().buckets());
+
+        PortNumber[] removePorts = {PortNumber.portNumber(31),
+                PortNumber.portNumber(32)};
+        List<PortNumber> outPorts = new ArrayList<>();
+        outPorts.addAll(Arrays.asList(removePorts));
+        List<GroupBucket> removeBuckets = new ArrayList<>();
+        for (PortNumber portNumber : outPorts) {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(portNumber)
+                    .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
+                    .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                    .pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(106));
+            removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+            buckets.remove(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+        }
+        GroupBuckets groupRemoveBuckets = new GroupBuckets(removeBuckets);
+        groupManager.removeBucketsFromGroup(deviceId,
+                                            prevKey,
+                                            groupRemoveBuckets,
+                                            removeKey,
+                                            appId);
+        GroupBuckets updatedBuckets = new GroupBuckets(buckets);
+        List<GroupOperation> expectedGroupOps = Collections.singletonList(
+                GroupOperation.createModifyGroupOperation(createdGroup.id(),
+                                                          Group.Type.SELECT,
+                                                          updatedBuckets));
+        if (deviceId.equals(VDID1)) {
+            provider.validate(networkId, deviceId, expectedGroupOps);
+        }
+
+        Group existingGroup = groupManager.getGroup(deviceId, removeKey);
+        List<Group> groupEntries = Collections.singletonList(existingGroup);
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        listener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_UPDATED));
+    }
+
+    // Test group remove operations
+    private void testRemoveGroup(NetworkId networkId, DeviceId deviceId) {
+        VirtualNetworkGroupManager groupManager;
+        VirtualGroupProviderService providerService;
+        TestGroupListener listener;
+
+        if (networkId.id() == 1) {
+            groupManager = groupManager1;
+            providerService = providerService1;
+            listener = listener1;
+        } else {
+            groupManager = groupManager2;
+            providerService = providerService2;
+            listener = listener2;
+        }
+
+        GroupKey currKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
+        Group existingGroup = groupManager.getGroup(deviceId, currKey);
+        groupManager.removeGroup(deviceId, currKey, appId);
+        List<GroupOperation> expectedGroupOps = Collections.singletonList(
+                GroupOperation.createDeleteGroupOperation(existingGroup.id(),
+                                                          Group.Type.SELECT));
+        if (deviceId.equals(VDID1)) {
+            provider.validate(networkId, deviceId, expectedGroupOps);
+        }
+
+        List<Group> groupEntries = Collections.emptyList();
+        providerService.pushGroupMetrics(deviceId, groupEntries);
+        listener.validateEvent(Collections.singletonList(GroupEvent.Type.GROUP_REMOVED));
+    }
+
+    private class TestGroupProvider extends AbstractVirtualProvider
+            implements VirtualGroupProvider {
+        NetworkId lastNetworkId;
+        DeviceId lastDeviceId;
+        List<GroupOperation> groupOperations = new ArrayList<>();
+
+        protected TestGroupProvider() {
+            super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
+        }
+
+        @Override
+        public void performGroupOperation(NetworkId networkId, DeviceId deviceId,
+                                          GroupOperations groupOps) {
+            lastNetworkId = networkId;
+            lastDeviceId = deviceId;
+            groupOperations.addAll(groupOps.operations());
+        }
+
+        public void validate(NetworkId expectedNetworkId, DeviceId expectedDeviceId,
+                             List<GroupOperation> expectedGroupOps) {
+            if (expectedGroupOps == null) {
+                assertTrue("events generated", groupOperations.isEmpty());
+                return;
+            }
+
+            assertEquals(lastNetworkId, expectedNetworkId);
+            assertEquals(lastDeviceId, expectedDeviceId);
+            assertTrue((this.groupOperations.containsAll(expectedGroupOps) &&
+                    expectedGroupOps.containsAll(groupOperations)));
+
+            groupOperations.clear();
+            lastDeviceId = null;
+            lastNetworkId = null;
+        }
+    }
+
+    private static class TestGroupListener implements GroupListener {
+        final List<GroupEvent> events = new ArrayList<>();
+
+        @Override
+        public void event(GroupEvent event) {
+            events.add(event);
+        }
+
+        public void validateEvent(List<GroupEvent.Type> expectedEvents) {
+            int i = 0;
+            System.err.println("events :" + events);
+            for (GroupEvent e : events) {
+                assertEquals("unexpected event", expectedEvents.get(i), e.type());
+                i++;
+            }
+            assertEquals("mispredicted number of events",
+                         expectedEvents.size(), events.size());
+            events.clear();
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManagerTest.java
new file mode 100644
index 0000000..e60d343
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManagerTest.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl;
+
+import com.google.common.collect.Iterators;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.TestDeviceParams;
+import org.onosproject.net.host.HostService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import static org.junit.Assert.*;
+
+/**
+ * Junit tests for VirtualNetworkHostService.
+ */
+public class VirtualNetworkHostManagerTest extends TestDeviceParams {
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private TestServiceDirectory testDirectory;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+    }
+
+    /**
+     * Sets up a virtual network with hosts.
+     *
+     * @return virtual network
+     */
+    private VirtualNetwork setupVnet() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        ConnectPoint hostCp1 = new ConnectPoint(DID1, P1);
+        ConnectPoint hostCp2 = new ConnectPoint(DID2, P2);
+        manager.createVirtualPort(virtualNetwork.id(), hostCp1.deviceId(), hostCp1.port(),
+                new ConnectPoint(virtualDevice1.id(), hostCp1.port()));
+        manager.createVirtualPort(virtualNetwork.id(), hostCp2.deviceId(), hostCp2.port(),
+                new ConnectPoint(virtualDevice2.id(), hostCp2.port()));
+
+        manager.createVirtualHost(virtualNetwork.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+        manager.createVirtualHost(virtualNetwork.id(), HID2, MAC2, VLAN2, LOC2, IPSET2);
+        return virtualNetwork;
+    }
+
+    /**
+     * Sets up a virtual network with no hosts.
+     *
+     * @return virtual network
+     */
+    private VirtualNetwork setupEmptyVnet() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        ConnectPoint hostCp1 = new ConnectPoint(DID1, P1);
+        ConnectPoint hostCp2 = new ConnectPoint(DID2, P2);
+        manager.createVirtualPort(virtualNetwork.id(), hostCp1.deviceId(), hostCp1.port(),
+                new ConnectPoint(virtualDevice1.id(), hostCp1.port()));
+        manager.createVirtualPort(virtualNetwork.id(), hostCp2.deviceId(), hostCp2.port(),
+                new ConnectPoint(virtualDevice2.id(), hostCp2.port()));
+
+        return virtualNetwork;
+    }
+
+    /**
+     * Tests the getHosts(), getHost(), getHostsByXX(), getConnectedHosts() methods
+     * on a non-empty virtual network.
+     */
+    @Test
+    public void testGetHostsOnNonEmptyVnet() {
+        VirtualNetwork virtualNetwork = setupEmptyVnet();
+        VirtualHost vhost1 = manager.createVirtualHost(virtualNetwork.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+        VirtualHost vhost2 = manager.createVirtualHost(virtualNetwork.id(), HID2, MAC2, VLAN2, LOC2, IPSET2);
+        HostService hostService = manager.get(virtualNetwork.id(), HostService.class);
+
+        // test the getHosts() and getHostCount() methods
+        Iterator<Host> itHosts = hostService.getHosts().iterator();
+        assertEquals("The host set size did not match.", 2, Iterators.size(itHosts));
+        assertEquals("The host count did not match.", 2, hostService.getHostCount());
+
+        // test the getHost() method
+        Host testHost = hostService.getHost(HID2);
+        assertEquals("The expected host did not match.", vhost2, testHost);
+
+        // test the getHostsByVlan(...) method
+        Collection<Host> collHost = hostService.getHostsByVlan(VLAN1);
+        assertEquals("The host set size did not match.", 1, collHost.size());
+        assertTrue("The host did not match.", collHost.contains(vhost1));
+
+        // test the getHostsByMac(...) method
+        collHost = hostService.getHostsByMac(MAC2);
+        assertEquals("The host set size did not match.", 1, collHost.size());
+        assertTrue("The host did not match.", collHost.contains(vhost2));
+
+        // test the getHostsByIp(...) method
+        collHost = hostService.getHostsByIp(IP1);
+        assertEquals("The host set size did not match.", 2, collHost.size());
+        collHost = hostService.getHostsByIp(IP2);
+        assertEquals("The host set size did not match.", 1, collHost.size());
+        assertTrue("The host did not match.", collHost.contains(vhost1));
+
+        // test the getConnectedHosts(ConnectPoint) method
+        collHost = hostService.getConnectedHosts(LOC1);
+        assertEquals("The host set size did not match.", 1, collHost.size());
+        assertTrue("The host did not match.", collHost.contains(vhost1));
+
+        // test the getConnectedHosts(DeviceId) method
+        collHost = hostService.getConnectedHosts(DID2);
+        assertEquals("The host set size did not match.", 1, collHost.size());
+        assertTrue("The host did not match.", collHost.contains(vhost2));
+    }
+
+    /**
+     * Tests the getHosts(), getHost(), getHostsByXX(), getConnectedHosts() methods
+     * on an empty virtual network.
+     */
+    @Test
+    public void testGetHostsOnEmptyVnet() {
+        VirtualNetwork virtualNetwork = setupEmptyVnet();
+        HostService hostService = manager.get(virtualNetwork.id(), HostService.class);
+
+        // test the getHosts() and getHostCount() methods
+        Iterator<Host> itHosts = hostService.getHosts().iterator();
+        assertEquals("The host set size did not match.", 0, Iterators.size(itHosts));
+        assertEquals("The host count did not match.", 0, hostService.getHostCount());
+
+        // test the getHost() method
+        Host testHost = hostService.getHost(HID2);
+        assertNull("The host should be null.", testHost);
+
+        // test the getHostsByVlan(...) method
+        Collection<Host> collHost = hostService.getHostsByVlan(VLAN1);
+        assertEquals("The host set size did not match.", 0, collHost.size());
+
+        // test the getHostsByMac(...) method
+        collHost = hostService.getHostsByMac(MAC2);
+        assertEquals("The host set size did not match.", 0, collHost.size());
+
+        // test the getHostsByIp(...) method
+        collHost = hostService.getHostsByIp(IP1);
+        assertEquals("The host set size did not match.", 0, collHost.size());
+
+        // test the getConnectedHosts(ConnectPoint) method
+        collHost = hostService.getConnectedHosts(LOC1);
+        assertEquals("The host set size did not match.", 0, collHost.size());
+
+        // test the getConnectedHosts(DeviceId) method
+        collHost = hostService.getConnectedHosts(DID2);
+        assertEquals("The host set size did not match.", 0, collHost.size());
+    }
+
+    /**
+     * Tests querying for a host using a null host identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetHostByNullId() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getHost(null);
+    }
+
+    /**
+     * Tests querying for hosts with null mac.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetHostsByNullMac() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getHostsByMac(null);
+    }
+
+    /**
+     * Tests querying for hosts with null vlan.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetHostsByNullVlan() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getHostsByVlan(null);
+    }
+
+    /**
+     * Tests querying for hosts with null ip.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetHostsByNullIp() {
+        VirtualNetwork vnet = setupVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getHostsByIp(null);
+    }
+
+    /**
+     * Tests querying for connected hosts with null host location (connect point).
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetConnectedHostsByNullLoc() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getConnectedHosts((ConnectPoint) null);
+    }
+
+    /**
+     * Tests querying for connected hosts with null device id.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetConnectedHostsByNullDeviceId() {
+        VirtualNetwork vnet = setupVnet();
+        HostService hostService = manager.get(vnet.id(), HostService.class);
+
+        hostService.getConnectedHosts((DeviceId) null);
+    }
+
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentManagerTest.java
new file mode 100644
index 0000000..ba0adda
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentManagerTest.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl;
+
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.TestApplicationId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntentStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualIntentStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.FakeIntentManager;
+import org.onosproject.net.intent.FlowRuleIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentCompiler;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.IntentTestsMocks;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MockIdGenerator;
+import org.onosproject.net.intent.PathIntent;
+import org.onosproject.net.intent.TestableIntentService;
+import org.onosproject.net.intent.WorkPartitionService;
+import org.onosproject.net.intent.WorkPartitionServiceAdapter;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Junit tests for VirtualNetworkIntentService.
+ */
+@Ignore("deprecated prototype implementation")
+public class VirtualNetworkIntentManagerTest extends TestDeviceParams {
+
+    private final String tenantIdValue1 = "TENANT_ID1";
+    private static final ApplicationId APP_ID =
+            new TestApplicationId("MyAppId");
+
+    private ConnectPoint cp1;
+    private ConnectPoint cp2;
+    private ConnectPoint cp3;
+    private ConnectPoint cp4;
+    private ConnectPoint cp5;
+    private ConnectPoint cp6;
+    private VirtualLink link1;
+    private VirtualLink link2;
+    private VirtualLink link3;
+    private VirtualLink link4;
+    private VirtualLink link5;
+    private VirtualLink link6;
+
+    private VirtualNetworkManager manager;
+    private static DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private VirtualNetworkIntentStore intentStore;
+    private CoreService coreService;
+    private TestableIntentService intentService = new FakeIntentManager();
+    private VirtualNetworkIntentManager vnetIntentService;
+    private TestIntentCompiler compiler = new TestIntentCompiler();
+    private IntentExtensionService intentExtensionService;
+    private WorkPartitionService workPartitionService;
+    private ServiceDirectory testDirectory;
+    private TestListener listener = new TestListener();
+    private static final int MAX_WAIT_TIME = 5;
+    private static final int MAX_PERMITS = 1;
+    private static Semaphore created;
+    private static Semaphore withdrawn;
+    private static Semaphore purged;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+        intentStore = new SimpleVirtualIntentStore();
+
+        coreService = new VirtualNetworkIntentManagerTest.TestCoreService();
+
+        MockIdGenerator.cleanBind();
+
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+        intentService.addListener(listener);
+
+        // Register a compiler and an installer both setup for success.
+        intentExtensionService = intentService;
+        intentExtensionService.registerCompiler(VirtualNetworkIntent.class, compiler);
+
+        created = new Semaphore(0, true);
+        withdrawn = new Semaphore(0, true);
+        purged = new Semaphore(0, true);
+
+        workPartitionService = new WorkPartitionServiceAdapter();
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(IntentService.class, intentService)
+                .add(WorkPartitionService.class, workPartitionService);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+        MockIdGenerator.unbind();
+        intentService.removeListener(listener);
+        created = null;
+        withdrawn = null;
+        purged = null;
+    }
+
+    /**
+     * Method to create the virtual network for further testing.
+     *
+     * @return virtual network
+     */
+    private VirtualNetwork setupVirtualNetworkTopology() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        VirtualDevice virtualDevice3 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID3);
+        VirtualDevice virtualDevice4 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID4);
+
+        Port port1 = new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true);
+        cp1 = new ConnectPoint(virtualDevice1.id(), port1.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port1.number(), cp1);
+
+        Port port2 = new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true);
+        cp2 = new ConnectPoint(virtualDevice1.id(), port2.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port2.number(), cp2);
+
+        Port port3 = new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true);
+        cp3 = new ConnectPoint(virtualDevice2.id(), port3.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port3.number(), cp3);
+
+        Port port4 = new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true);
+        cp4 = new ConnectPoint(virtualDevice2.id(), port4.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port4.number(), cp4);
+
+        Port port5 = new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true);
+        cp5 = new ConnectPoint(virtualDevice3.id(), port5.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port5.number(), cp5);
+
+        Port port6 = new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true);
+        cp6 = new ConnectPoint(virtualDevice3.id(), port6.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port6.number(), cp6);
+
+        link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+        link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
+        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
+        link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
+        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
+
+        vnetIntentService = new VirtualNetworkIntentManager(manager, virtualNetwork.id());
+        vnetIntentService.intentStore = intentStore;
+        return virtualNetwork;
+    }
+
+    /**
+     * Tests the submit(), withdraw(), and purge() methods.
+     */
+    @Test
+    public void testCreateAndRemoveIntent() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        Key intentKey = Key.of("test", APP_ID);
+
+        List<Constraint> constraints = new ArrayList<>();
+        constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
+
+        VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
+                .networkId(virtualNetwork.id())
+                .key(intentKey)
+                .appId(APP_ID)
+                .ingressPoint(cp1)
+                .egressPoint(cp5)
+                .constraints(constraints)
+                .build();
+        // Test the submit() method.
+        vnetIntentService.submit(virtualIntent);
+
+        // Wait for the both intents to go into an INSTALLED state.
+        try {
+            if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for intent to get installed.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception during intent installation." + e.getMessage());
+        }
+
+        // Test the getIntentState() method
+        assertEquals("The intent state did not match as expected.", IntentState.INSTALLED,
+                     vnetIntentService.getIntentState(virtualIntent.key()));
+
+        // Test the withdraw() method.
+        vnetIntentService.withdraw(virtualIntent);
+        // Wait for the both intents to go into a WITHDRAWN state.
+        try {
+            if (!withdrawn.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for intent to get withdrawn.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception during intent withdrawal." + e.getMessage());
+        }
+
+        // Test the getIntentState() method
+        assertEquals("The intent state did not match as expected.", IntentState.WITHDRAWN,
+                     vnetIntentService.getIntentState(virtualIntent.key()));
+
+        // Test the purge() method.
+        vnetIntentService.purge(virtualIntent);
+        // Wait for the both intents to be removed/purged.
+        try {
+            if (!purged.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for intent to get purged.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception during intent purging." + e.getMessage());
+        }
+
+    }
+
+    /**
+     * Tests the getIntents, getIntent(), getIntentData(), getIntentCount(),
+     * isLocal() methods.
+     */
+    @Test
+    public void testGetIntents() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        Key intentKey = Key.of("test", APP_ID);
+
+        List<Constraint> constraints = new ArrayList<>();
+        constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
+
+        VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
+                .networkId(virtualNetwork.id())
+                .key(intentKey)
+                .appId(APP_ID)
+                .ingressPoint(cp1)
+                .egressPoint(cp5)
+                .constraints(constraints)
+                .build();
+        // Test the submit() method.
+        vnetIntentService.submit(virtualIntent);
+
+        // Wait for the both intents to go into an INSTALLED state.
+        try {
+            if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for intent to get installed.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception during intent installation." + e.getMessage());
+        }
+
+        // Test the getIntents() method
+        assertEquals("The intents size did not match as expected.", 1,
+                     Iterators.size(vnetIntentService.getIntents().iterator()));
+
+        // Test the getIntent() method
+        assertNotNull("The intent should have been found.", vnetIntentService.getIntent(virtualIntent.key()));
+
+        // Test the getIntentData() method
+        assertEquals("The intent data size did not match as expected.", 1,
+                     Iterators.size(vnetIntentService.getIntentData().iterator()));
+
+        // Test the getIntentCount() method
+        assertEquals("The intent count did not match as expected.", 1,
+                     vnetIntentService.getIntentCount());
+
+        // Test the isLocal() method
+        assertTrue("The intent should be local.", vnetIntentService.isLocal(virtualIntent.key()));
+
+    }
+
+    /**
+     * Test listener to listen for intent events.
+     */
+    private static class TestListener implements IntentListener {
+
+        @Override
+        public void event(IntentEvent event) {
+            switch (event.type()) {
+                case INSTALLED:
+                    // Release one permit on the created semaphore since the Intent event was received.
+//                    virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.INSTALLED);
+                    created.release();
+                    break;
+                case WITHDRAWN:
+                    // Release one permit on the removed semaphore since the Intent event was received.
+//                    virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.WITHDRAWN);
+                    withdrawn.release();
+                    break;
+                case PURGED:
+                    // Release one permit on the purged semaphore since the Intent event was received.
+                    purged.release();
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Core service test class.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+    }
+
+    private static class TestIntentCompiler implements IntentCompiler<VirtualNetworkIntent> {
+        @Override
+        public List<Intent> compile(VirtualNetworkIntent intent, List<Intent> installable) {
+            return Lists.newArrayList(new MockInstallableIntent());
+        }
+    }
+
+    private static class MockInstallableIntent extends FlowRuleIntent {
+
+        public MockInstallableIntent() {
+            super(APP_ID, null, Collections.singletonList(new IntentTestsMocks.MockFlowRule(100)),
+                    Collections.emptyList(), PathIntent.ProtectionType.PRIMARY, null);
+        }
+    }
+
+//    private void addOrUpdateIntent(Intent intent, IntentState state) {
+//        checkNotNull(intent, "Intent cannot be null");
+//        IntentData intentData = intentStore.(intent.key());
+//        if (intentData == null) {
+//            intentData = new IntentData(intent, state, new WallClockTimestamp(System.currentTimeMillis()));
+//        } else {
+//            intentData = new IntentData(intent, state, intentData.version());
+//        }
+//        intentKeyIntentDataMap.put(intent.key(), intentData);
+//    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManagerTest.java
new file mode 100644
index 0000000..2805f9e
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManagerTest.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl;
+
+import com.google.common.collect.Iterators;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+/**
+ * Junit tests for VirtualNetworkLinkService.
+ */
+public class VirtualNetworkLinkManagerTest extends TestDeviceParams {
+
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService;
+    private TestServiceDirectory testDirectory;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        coreService = new VirtualNetworkLinkManagerTest.TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+    }
+
+    /**
+     * Tests the getLinks(), getActiveLinks(), getLinkCount(), getLink(),
+     * getLinks(ConnectPoint), getDeviceLinks(), getDeviceEgressLinks(), getDeviceIngressLinks(),
+     * getEgressLinks(), getIngressLinks() methods.
+     */
+    @Test
+    public void testGetLinks() {
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), src.deviceId(), src.port(),
+                                  new ConnectPoint(srcVirtualDevice.id(), src.port()));
+
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), dst.deviceId(), dst.port(),
+                                  new ConnectPoint(dstVirtualDevice.id(), dst.port()));
+
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), src, dst);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), dst, src);
+
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getLinks() method
+        Iterator<Link> it = linkService.getLinks().iterator();
+        assertEquals("The link set size did not match.", 2, Iterators.size(it));
+
+        // test the getActiveLinks() method where all links are INACTIVE
+        Iterator<Link> it2 = linkService.getActiveLinks().iterator();
+        assertEquals("The link set size did not match.", 0, Iterators.size(it2));
+
+        // test the getActiveLinks() method where one link is ACTIVE
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        Iterator<Link> it3 = linkService.getActiveLinks().iterator();
+        assertEquals("The link set size did not match.", 1, Iterators.size(it3));
+
+        // test the getLinkCount() method
+        assertEquals("The link set size did not match.", 2, linkService.getLinkCount());
+
+        // test the getLink() method
+        assertEquals("The expect link did not match.", link1,
+                     linkService.getLink(src, dst));
+        assertEquals("The expect link did not match.", link2,
+                     linkService.getLink(dst, src));
+        assertNotEquals("The expect link should not have matched.", link1,
+                        linkService.getLink(dst, src));
+
+        // test the getLinks(ConnectPoint) method
+        assertEquals("The link set size did not match.", 2, linkService.getLinks(src).size());
+        assertEquals("The link set size did not match.", 2, linkService.getLinks(dst).size());
+        ConnectPoint connectPoint = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(3));
+        assertEquals("The link set size did not match.", 0, linkService.getLinks(connectPoint).size());
+
+        // test the getDeviceLinks() method
+        assertEquals("The link set size did not match.", 2,
+                     linkService.getDeviceLinks(DID1).size());
+        assertEquals("The link set size did not match.", 2,
+                     linkService.getDeviceLinks(DID2).size());
+        assertEquals("The link set size did not match.", 0,
+                     linkService.getDeviceLinks(DID3).size());
+
+        // test the getDeviceEgressLinks() method
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getDeviceEgressLinks(DID1).size());
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getDeviceEgressLinks(DID2).size());
+        assertEquals("The link set size did not match.", 0,
+                     linkService.getDeviceEgressLinks(DID3).size());
+
+        // test the getDeviceIngressLinks() method
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getDeviceIngressLinks(DID1).size());
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getDeviceIngressLinks(DID2).size());
+        assertEquals("The link set size did not match.", 0,
+                     linkService.getDeviceIngressLinks(DID3).size());
+
+        // test the getEgressLinks() method
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getEgressLinks(src).size());
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getEgressLinks(dst).size());
+        assertEquals("The link set size did not match.", 0,
+                     linkService.getEgressLinks(connectPoint).size());
+
+        // test the getIngressLinks() method
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getIngressLinks(src).size());
+        assertEquals("The link set size did not match.", 1,
+                     linkService.getIngressLinks(dst).size());
+        assertEquals("The link set size did not match.", 0,
+                     linkService.getIngressLinks(connectPoint).size());
+    }
+
+    /**
+     * Tests the getLink() method using a null src connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetLinkByNullSrc() {
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualLink(virtualNetwork.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork.id(), dst, src);
+
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getLink() method with a null src connect point.
+        linkService.getLink(null, dst);
+    }
+
+    /**
+     * Tests the getLink() method using a null dst connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetLinkByNullDst() {
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualLink(virtualNetwork.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork.id(), dst, src);
+
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getLink() method with a null dst connect point.
+        linkService.getLink(src, null);
+    }
+
+    /**
+     * Tests querying for links using a null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDeviceLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getDeviceLinks() method with a null device identifier.
+        linkService.getDeviceLinks(null);
+    }
+
+    /**
+     * Tests querying for links using a null connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getLinks() method with a null connect point.
+        linkService.getLinks(null);
+    }
+
+    /**
+     * Tests querying for device egress links using a null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDeviceEgressLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getDeviceEgressLinks() method with a null device identifier.
+        linkService.getDeviceEgressLinks(null);
+    }
+
+    /**
+     * Tests querying for device ingress links using a null device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDeviceIngressLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getDeviceIngressLinks() method with a null device identifier.
+        linkService.getDeviceIngressLinks(null);
+    }
+
+    /**
+     * Tests querying for egress links using a null connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetEgressLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getEgressLinks() method with a null connect point.
+        linkService.getEgressLinks(null);
+    }
+
+    /**
+     * Tests querying for ingress links using a null connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetIngressLinksByNullId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        LinkService linkService = manager.get(virtualNetwork.id(), LinkService.class);
+
+        // test the getIngressLinks() method with a null connect point.
+        linkService.getIngressLinks(null);
+    }
+
+    /**
+     * Core service test class.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
new file mode 100644
index 0000000..9156c38
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
@@ -0,0 +1,1003 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl;
+
+import com.google.common.collect.Lists;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestTools;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.event.Event;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkGroupStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntentStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkListener;
+import org.onosproject.incubator.net.virtual.VirtualNetworkPacketStore;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.incubator.net.virtual.impl.provider.DefaultVirtualFlowRuleProvider;
+import org.onosproject.incubator.net.virtual.impl.provider.DefaultVirtualGroupProvider;
+import org.onosproject.incubator.net.virtual.impl.provider.DefaultVirtualNetworkProvider;
+import org.onosproject.incubator.net.virtual.impl.provider.DefaultVirtualPacketProvider;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowRuleStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualGroupStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualIntentStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualPacketStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MockIdGenerator;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.*;
+import static org.onosproject.net.NetTestTools.APP_ID;
+
+/**
+ * Junit tests for VirtualNetworkManager.
+ */
+public class VirtualNetworkManagerTest extends VirtualNetworkTestUtil {
+    private final String tenantIdValue1 = "TENANT_ID1";
+    private final String tenantIdValue2 = "TENANT_ID2";
+
+    private VirtualNetworkManager manager;
+    private DefaultVirtualNetworkProvider topologyProvider;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService;
+    private TestListener listener = new TestListener();
+    private TopologyService topologyService;
+
+    private ConnectPoint cp6;
+    private ConnectPoint cp7;
+
+    private TestServiceDirectory testDirectory;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+        MockIdGenerator.cleanBind();
+
+        coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService",
+                           new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.addListener(listener);
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.removeListener(listener);
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+        MockIdGenerator.cleanBind();
+    }
+
+    /**
+     * Tests registering a null tenant id.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testRegisterNullTenantId() {
+        manager.registerTenantId(null);
+    }
+
+    /**
+     * Tests registering/unregistering a tenant id.
+     */
+    @Test
+    public void testRegisterUnregisterTenantId() {
+        manager.unregisterTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue2));
+        Collection<TenantId> tenantIdCollection = manager.getTenantIds();
+        assertEquals("The tenantId set size did not match.", 2, tenantIdCollection.size());
+
+        manager.unregisterTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.unregisterTenantId(TenantId.tenantId(tenantIdValue2));
+        tenantIdCollection = manager.getTenantIds();
+        assertTrue("The tenantId set should be empty.", tenantIdCollection.isEmpty());
+
+        // Validate that the events were all received in the correct order.
+        validateEvents(VirtualNetworkEvent.Type.TENANT_REGISTERED,
+                       VirtualNetworkEvent.Type.TENANT_REGISTERED,
+                       VirtualNetworkEvent.Type.TENANT_UNREGISTERED,
+                       VirtualNetworkEvent.Type.TENANT_UNREGISTERED);
+    }
+
+    /**
+     * Test method {@code getTenantId()} for registered virtual network.
+     */
+    @Test
+    public void testGetTenantIdForRegisteredVirtualNetwork() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(tenantIdValue1);
+        TenantId tenantId = manager.getTenantId(virtualNetwork.id());
+
+        assertThat(tenantId.toString(), is(tenantIdValue1));
+    }
+
+    /**
+     * Test method {@code getTenantId()} for null virtual network id.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetTenantIdForNullVirtualNetwork() {
+        manager.getTenantId(null);
+    }
+
+    /**
+     * Test method {@code getVirtualNetwork()} for registered virtual network.
+     */
+    @Test
+    public void testGetVirtualNetworkForRegisteredNetwork() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(tenantIdValue1);
+
+        assertNotNull("Registered virtual network is null", manager.getVirtualNetwork(virtualNetwork.id()));
+    }
+
+    /**
+     * Test method {@code getVirtualNetwork()} for null virtual network id.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetVirtualForNullVirtualNetworkId() {
+        manager.getVirtualNetwork(null);
+    }
+
+    /**
+     * Tests adding a null virtual network.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testCreateNullVirtualNetwork() {
+        manager.createVirtualNetwork(null);
+    }
+
+    /**
+     * Tests removal of a virtual network twice.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testRemoveVnetTwice() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        manager.removeVirtualNetwork(virtualNetwork.id());
+        manager.removeVirtualNetwork(virtualNetwork.id());
+    }
+
+    /**
+     * Tests add and remove of virtual networks.
+     */
+    @Test
+    public void testAddRemoveVirtualNetwork() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        Set<VirtualNetwork> virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
+        assertNotNull("The virtual network set should not be null", virtualNetworks);
+        assertEquals("The virtual network set size did not match.", 2, virtualNetworks.size());
+
+        int remaining = virtualNetworks.size();
+        for (VirtualNetwork virtualNetwork : virtualNetworks) {
+            manager.removeVirtualNetwork(virtualNetwork.id());
+            assertEquals("The expected virtual network size does not match",
+                         --remaining, manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1)).size());
+        }
+        virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
+        assertTrue("The virtual network set should be empty.", virtualNetworks.isEmpty());
+
+        // Create/remove a virtual network.
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        manager.removeVirtualNetwork(virtualNetwork.id());
+
+        virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
+        assertTrue("The virtual network set should be empty.", virtualNetworks.isEmpty());
+
+        // Validate that the events were all received in the correct order.
+        validateEvents(VirtualNetworkEvent.Type.TENANT_REGISTERED,
+                       VirtualNetworkEvent.Type.NETWORK_ADDED,
+                       VirtualNetworkEvent.Type.NETWORK_ADDED,
+                       VirtualNetworkEvent.Type.NETWORK_REMOVED,
+                       VirtualNetworkEvent.Type.NETWORK_REMOVED,
+                       VirtualNetworkEvent.Type.NETWORK_ADDED,
+                       VirtualNetworkEvent.Type.NETWORK_REMOVED);
+    }
+
+    /**
+     * Tests adding a null virtual device.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testCreateNullVirtualDevice() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        manager.createVirtualDevice(virtualNetwork.id(), null);
+    }
+
+    /**
+     * Tests adding a virtual device where no virtual network exists.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testCreateVirtualDeviceWithNoNetwork() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork =
+                new DefaultVirtualNetwork(NetworkId.NONE,
+                                          TenantId.tenantId(tenantIdValue1));
+
+        manager.createVirtualDevice(virtualNetwork.id(), DID1);
+    }
+
+    /**
+     * Tests add and remove of virtual devices.
+     */
+    @Test
+    public void testAddRemoveVirtualDevice() {
+        List<VirtualNetworkEvent.Type> expectedEventTypes = new ArrayList<>();
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        expectedEventTypes.add(VirtualNetworkEvent.Type.TENANT_REGISTERED);
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        expectedEventTypes.add(VirtualNetworkEvent.Type.NETWORK_ADDED);
+        VirtualNetwork virtualNetwork2 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        expectedEventTypes.add(VirtualNetworkEvent.Type.NETWORK_ADDED);
+        manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_ADDED);
+        manager.createVirtualDevice(virtualNetwork2.id(), DID2);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_ADDED);
+
+        Set<VirtualDevice> virtualDevices1 = manager.getVirtualDevices(virtualNetwork1.id());
+        assertNotNull("The virtual device set should not be null", virtualDevices1);
+        assertEquals("The virtual device set size did not match.", 1, virtualDevices1.size());
+
+        Set<VirtualDevice> virtualDevices2 = manager.getVirtualDevices(virtualNetwork2.id());
+        assertNotNull("The virtual device set should not be null", virtualDevices2);
+        assertEquals("The virtual device set size did not match.", 1, virtualDevices2.size());
+
+        for (VirtualDevice virtualDevice : virtualDevices1) {
+            manager.removeVirtualDevice(virtualNetwork1.id(), virtualDevice.id());
+            expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_REMOVED);
+            // attempt to remove the same virtual device again - no event expected.
+            manager.removeVirtualDevice(virtualNetwork1.id(), virtualDevice.id());
+        }
+        virtualDevices1 = manager.getVirtualDevices(virtualNetwork1.id());
+        assertTrue("The virtual device set should be empty.", virtualDevices1.isEmpty());
+
+        // Add/remove the virtual device again.
+        VirtualDevice virtualDevice = manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_ADDED);
+        manager.removeVirtualDevice(virtualDevice.networkId(), virtualDevice.id());
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_REMOVED);
+        virtualDevices1 = manager.getVirtualDevices(virtualNetwork1.id());
+        assertTrue("The virtual device set should be empty.", virtualDevices1.isEmpty());
+
+        // Validate that the events were all received in the correct order.
+        validateEvents(expectedEventTypes.toArray(
+                new VirtualNetworkEvent.Type[expectedEventTypes.size()]));
+    }
+
+    /**
+     * Tests getting a collection of physical device identifier corresponding to
+     * the specified virtual device.
+     */
+    @Test
+    public void testGetPhysicalDevices() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue2));
+
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork2 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue2));
+
+        // two virtual device in first virtual network
+        VirtualDevice vDevice1InVnet1 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        VirtualDevice vDevice2InVnet1 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID2);
+        // Two virtual device in second virtual network
+        VirtualDevice vDevice1InVnet2 =
+                manager.createVirtualDevice(virtualNetwork2.id(), DID1);
+        VirtualDevice vDevice2InVnet2 =
+                manager.createVirtualDevice(virtualNetwork2.id(), DID2);
+
+        // Connection Point from each physical device
+        // Virtual network 1
+        ConnectPoint cp1InVnet1 =
+                new ConnectPoint(PHYDID1, PortNumber.portNumber(10));
+        ConnectPoint cp2InVnet1 =
+                new ConnectPoint(PHYDID2, PortNumber.portNumber(20));
+        ConnectPoint cp3InVnet1 =
+                new ConnectPoint(PHYDID3, PortNumber.portNumber(30));
+        ConnectPoint cp4InVnet1 =
+                new ConnectPoint(PHYDID4, PortNumber.portNumber(40));
+        // Virtual network 2
+        ConnectPoint cp1InVnet2 =
+                new ConnectPoint(PHYDID1, PortNumber.portNumber(10));
+        ConnectPoint cp2InVnet2 =
+                new ConnectPoint(PHYDID2, PortNumber.portNumber(20));
+        ConnectPoint cp3InVnet2 =
+                new ConnectPoint(PHYDID3, PortNumber.portNumber(30));
+        ConnectPoint cp4InVnet2 =
+                new ConnectPoint(PHYDID4, PortNumber.portNumber(40));
+
+        // Make simple BigSwitch by mapping two phyDevice to one vDevice
+        // First vDevice in first virtual network
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice1InVnet1.id(), PortNumber.portNumber(1), cp1InVnet1);
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice1InVnet1.id(), PortNumber.portNumber(2), cp2InVnet1);
+        // Second vDevice in first virtual network
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice2InVnet1.id(), PortNumber.portNumber(1), cp3InVnet1);
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice2InVnet1.id(), PortNumber.portNumber(2), cp4InVnet1);
+        // First vDevice in second virtual network
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice1InVnet2.id(), PortNumber.portNumber(1), cp1InVnet2);
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice1InVnet2.id(), PortNumber.portNumber(2), cp2InVnet2);
+        // Second vDevice in second virtual network
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice2InVnet2.id(), PortNumber.portNumber(1), cp3InVnet2);
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice2InVnet2.id(), PortNumber.portNumber(2), cp4InVnet2);
+
+
+        Set<DeviceId> physicalDeviceSet;
+        Set<DeviceId> testSet = new HashSet<>();
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork1.id(), vDevice1InVnet1.id());
+        testSet.add(PHYDID1);
+        testSet.add(PHYDID2);
+        assertEquals("The physical devices 1 did not match", testSet, physicalDeviceSet);
+        testSet.clear();
+
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork1.id(), vDevice2InVnet1.id());
+        testSet.add(PHYDID3);
+        testSet.add(PHYDID4);
+        assertEquals("The physical devices 2 did not match", testSet, physicalDeviceSet);
+        testSet.clear();
+
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork2.id(), vDevice1InVnet2.id());
+        testSet.add(PHYDID1);
+        testSet.add(PHYDID2);
+        assertEquals("The physical devices 1 did not match", testSet, physicalDeviceSet);
+        testSet.clear();
+
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork2.id(), vDevice2InVnet2.id());
+        testSet.add(PHYDID3);
+        testSet.add(PHYDID4);
+        assertEquals("The physical devices 2 did not match", testSet, physicalDeviceSet);
+        testSet.clear();
+    }
+
+    /**
+     * Tests adding a null virtual host.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testCreateNullVirtualHost() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        manager.createVirtualHost(virtualNetwork.id(), null, null, null, null, null);
+    }
+
+    /**
+     * Tests adding a virtual host where no virtual network exists.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testCreateVirtualHostWithNoNetwork() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork =
+                new DefaultVirtualNetwork(NetworkId.NONE, TenantId.tenantId(tenantIdValue1));
+
+        manager.createVirtualHost(virtualNetwork.id(), HID1, null, null, null, null);
+    }
+
+    /**
+     * Tests adding a virtual host where no virtual port exists.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testCreateVirtualHostWithNoVirtualPort() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        manager.createVirtualHost(virtualNetwork1.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+    }
+
+    /**
+     * Tests add and remove of virtual hosts.
+     */
+    @Test
+    public void testAddRemoveVirtualHost() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork2 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork2.id(), DID2);
+
+        ConnectPoint hostCp1 = new ConnectPoint(DID1, P1);
+        ConnectPoint hostCp2 = new ConnectPoint(DID2, P2);
+        manager.createVirtualPort(virtualNetwork1.id(), hostCp1.deviceId(), hostCp1.port(),
+                new ConnectPoint(virtualDevice1.id(), hostCp1.port()));
+        manager.createVirtualPort(virtualNetwork2.id(), hostCp2.deviceId(), hostCp2.port(),
+                new ConnectPoint(virtualDevice2.id(), hostCp2.port()));
+
+        manager.createVirtualHost(virtualNetwork1.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+        manager.createVirtualHost(virtualNetwork2.id(), HID2, MAC2, VLAN2, LOC2, IPSET2);
+
+        Set<VirtualHost> virtualHosts1 = manager.getVirtualHosts(virtualNetwork1.id());
+        assertNotNull("The virtual host set should not be null", virtualHosts1);
+        assertEquals("The virtual host set size did not match.", 1, virtualHosts1.size());
+
+        Set<VirtualHost> virtualHosts2 = manager.getVirtualHosts(virtualNetwork2.id());
+        assertNotNull("The virtual host set should not be null", virtualHosts2);
+        assertEquals("The virtual host set size did not match.", 1, virtualHosts2.size());
+
+        for (VirtualHost virtualHost : virtualHosts1) {
+            manager.removeVirtualHost(virtualNetwork1.id(), virtualHost.id());
+            // attempt to remove the same virtual host again.
+            manager.removeVirtualHost(virtualNetwork1.id(), virtualHost.id());
+        }
+        virtualHosts1 = manager.getVirtualHosts(virtualNetwork1.id());
+        assertTrue("The virtual host set should be empty.", virtualHosts1.isEmpty());
+
+        // Add/remove the virtual host again.
+        VirtualHost virtualHost =
+                manager.createVirtualHost(virtualNetwork1.id(),
+                                          HID1, MAC1, VLAN1, LOC1, IPSET1);
+        manager.removeVirtualHost(virtualHost.networkId(), virtualHost.id());
+        virtualHosts1 = manager.getVirtualHosts(virtualNetwork1.id());
+        assertTrue("The virtual host set should be empty.", virtualHosts1.isEmpty());
+    }
+
+    /**
+     * Tests add and remove of virtual links.
+     */
+    @Test
+    public void testAddRemoveVirtualLink() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID2);
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork1.id(), src.deviceId(), src.port(),
+                                  new ConnectPoint(srcVirtualDevice.id(), src.port()));
+
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork1.id(), dst.deviceId(), dst.port(),
+                                  new ConnectPoint(dstVirtualDevice.id(), dst.port()));
+
+        manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork1.id(), dst, src);
+
+        Set<VirtualLink> virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+        assertNotNull("The virtual link set should not be null", virtualLinks);
+        assertEquals("The virtual link set size did not match.", 2, virtualLinks.size());
+
+        for (VirtualLink virtualLink : virtualLinks) {
+            manager.removeVirtualLink(virtualLink.networkId(), virtualLink.src(), virtualLink.dst());
+            // attempt to remove the same virtual link again.
+            manager.removeVirtualLink(virtualLink.networkId(), virtualLink.src(), virtualLink.dst());
+        }
+        virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+        assertTrue("The virtual link set should be empty.", virtualLinks.isEmpty());
+
+        // Add/remove the virtual link again.
+        VirtualLink virtualLink = manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+        manager.removeVirtualLink(virtualLink.networkId(), virtualLink.src(), virtualLink.dst());
+        virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+        assertTrue("The virtual link set should be empty.", virtualLinks.isEmpty());
+    }
+
+    /**
+     * Tests adding the same virtual link twice.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testAddSameVirtualLink() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID2);
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork1.id(), src.deviceId(), src.port(),
+                                  new ConnectPoint(srcVirtualDevice.id(), src.port()));
+
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork1.id(), dst.deviceId(), dst.port(),
+                                  new ConnectPoint(dstVirtualDevice.id(), dst.port()));
+
+        manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+    }
+
+    private VirtualPort getPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
+        Set<VirtualPort> virtualPorts = manager.getVirtualPorts(networkId, deviceId);
+        return  virtualPorts.stream().filter(virtualPort -> virtualPort.number().equals(portNumber))
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Tests add, bind and remove of virtual ports.
+     */
+    @Test
+    public void testAddRemoveVirtualPort() {
+        List<VirtualNetworkEvent.Type> expectedEventTypes = new ArrayList<>();
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        expectedEventTypes.add(VirtualNetworkEvent.Type.TENANT_REGISTERED);
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        expectedEventTypes.add(VirtualNetworkEvent.Type.NETWORK_ADDED);
+        VirtualDevice virtualDevice =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_DEVICE_ADDED);
+        ConnectPoint cp = new ConnectPoint(virtualDevice.id(), PortNumber.portNumber(1));
+
+        manager.createVirtualPort(virtualNetwork1.id(),
+                                  virtualDevice.id(), PortNumber.portNumber(1), cp);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_ADDED);
+        manager.createVirtualPort(virtualNetwork1.id(),
+                                  virtualDevice.id(), PortNumber.portNumber(2), cp);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_ADDED);
+
+        Set<VirtualPort> virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), virtualDevice.id());
+        assertNotNull("The virtual port set should not be null", virtualPorts);
+        assertEquals("The virtual port set size did not match.", 2, virtualPorts.size());
+        virtualPorts.forEach(vp -> assertFalse("Initial virtual port state should be disabled", vp.isEnabled()));
+
+        // verify change state of virtual port (disabled -> enabled)
+        manager.updatePortState(virtualNetwork1.id(), virtualDevice.id(), PortNumber.portNumber(1), true);
+        VirtualPort changedPort = getPort(virtualNetwork1.id(), virtualDevice.id(), PortNumber.portNumber(1));
+        assertNotNull("The changed virtual port should not be null", changedPort);
+        assertEquals("Virtual port state should be enabled", true, changedPort.isEnabled());
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_UPDATED);
+
+        // verify change state of virtual port (disabled -> disabled)
+        manager.updatePortState(virtualNetwork1.id(), virtualDevice.id(), PortNumber.portNumber(2), false);
+        changedPort = getPort(virtualNetwork1.id(), virtualDevice.id(), PortNumber.portNumber(2));
+        assertNotNull("The changed virtual port should not be null", changedPort);
+        assertEquals("Virtual port state should be disabled", false, changedPort.isEnabled());
+        // no VIRTUAL_PORT_UPDATED event is expected - the requested state (disabled) is same as previous state.
+
+        for (VirtualPort virtualPort : virtualPorts) {
+            manager.removeVirtualPort(virtualNetwork1.id(),
+                                      (DeviceId) virtualPort.element().id(), virtualPort.number());
+            expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_REMOVED);
+            // attempt to remove the same virtual port again.
+            manager.removeVirtualPort(virtualNetwork1.id(),
+                                      (DeviceId) virtualPort.element().id(), virtualPort.number());
+        }
+        virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), virtualDevice.id());
+        assertTrue("The virtual port set should be empty.", virtualPorts.isEmpty());
+
+        // Add/remove the virtual port again.
+        VirtualPort virtualPort =
+                manager.createVirtualPort(virtualNetwork1.id(), virtualDevice.id(),
+                                                            PortNumber.portNumber(1), cp);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_ADDED);
+
+        ConnectPoint newCp = new ConnectPoint(DID2, PortNumber.portNumber(2));
+        manager.bindVirtualPort(virtualNetwork1.id(), virtualDevice.id(),
+                                PortNumber.portNumber(1), newCp);
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_UPDATED);
+
+        manager.removeVirtualPort(virtualNetwork1.id(),
+                                  (DeviceId) virtualPort.element().id(), virtualPort.number());
+        expectedEventTypes.add(VirtualNetworkEvent.Type.VIRTUAL_PORT_REMOVED);
+        virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), virtualDevice.id());
+        assertTrue("The virtual port set should be empty.", virtualPorts.isEmpty());
+
+        // Validate that the events were all received in the correct order.
+        validateEvents(expectedEventTypes.toArray(
+                new VirtualNetworkEvent.Type[expectedEventTypes.size()]));
+    }
+
+    /**
+     * Tests when a virtual element is removed, all the other elements depending on it are also removed.
+     */
+    @Test
+    public void testRemoveAllElements() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID2);
+        ConnectPoint src = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork1.id(), src.deviceId(), src.port(),
+                new ConnectPoint(PHYDID1, PortNumber.portNumber(1)));
+
+        ConnectPoint dst = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork1.id(), dst.deviceId(), dst.port(),
+                new ConnectPoint(PHYDID2, PortNumber.portNumber(2)));
+
+        manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork1.id(), dst, src);
+
+        ConnectPoint hostCp = new ConnectPoint(DID1, P1);
+        manager.createVirtualPort(virtualNetwork1.id(), hostCp.deviceId(), hostCp.port(),
+                new ConnectPoint(PHYDID1, P1));
+        manager.createVirtualHost(virtualNetwork1.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+
+        //When a virtual port is removed, all virtual links connected to it should also be removed.
+        manager.removeVirtualPort(virtualNetwork1.id(), DID1, PortNumber.portNumber(1));
+        Set<VirtualLink> virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+        assertTrue("The virtual link set should be empty.", virtualLinks.isEmpty());
+
+        //When a virtual port is removed, all virtual hosts located to it should also be removed.
+        manager.removeVirtualPort(virtualNetwork1.id(), DID1, P1);
+        Set<VirtualHost> virtualHosts = manager.getVirtualHosts(virtualNetwork1.id());
+        assertTrue("The virtual host set should be empty.", virtualHosts.isEmpty());
+
+        manager.createVirtualPort(virtualNetwork1.id(), src.deviceId(), src.port(),
+                new ConnectPoint(PHYDID1, PortNumber.portNumber(1)));
+        manager.createVirtualLink(virtualNetwork1.id(), src, dst);
+        manager.createVirtualLink(virtualNetwork1.id(), dst, src);
+        manager.createVirtualPort(virtualNetwork1.id(), hostCp.deviceId(), hostCp.port(),
+                new ConnectPoint(PHYDID1, P1));
+        manager.createVirtualHost(virtualNetwork1.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
+
+        //When a virtual device is removed, all virtual ports, hosts and links depended on it should also be removed.
+        manager.removeVirtualDevice(virtualNetwork1.id(), DID1);
+        Set<VirtualPort> virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), DID1);
+        assertTrue("The virtual port set of DID1 should be empty", virtualPorts.isEmpty());
+        virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+        assertTrue("The virtual link set should be empty.", virtualLinks.isEmpty());
+        virtualHosts = manager.getVirtualHosts(virtualNetwork1.id());
+        assertTrue("The virtual host set should be empty.", virtualHosts.isEmpty());
+
+        //When a tenantId is removed, all the virtual networks belonging to it should also be removed.
+        manager.unregisterTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        Set<VirtualNetwork> virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
+        assertNotNull("The virtual network set should not be null", virtualNetworks);
+        assertTrue("The virtual network set should be empty.", virtualNetworks.isEmpty());
+    }
+
+    /**
+     * Tests the addTunnelId() method in the store with a null intent.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testAddTunnelIdNullIntent() {
+        manager.store.addTunnelId(null, null);
+    }
+
+    /**
+     * Tests the removeTunnelId() method in the store with a null intent.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testRemoveTunnelIdNullIntent() {
+        manager.store.removeTunnelId(null, null);
+    }
+
+    /**
+     * Tests the addTunnelId, getTunnelIds(), removeTunnelId() methods with the store.
+     */
+    @Test
+    public void testAddTunnelId() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        ConnectPoint cp1 = new ConnectPoint(DID1, P1);
+        ConnectPoint cp2 = new ConnectPoint(DID2, P1);
+
+        VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
+                .networkId(virtualNetwork.id())
+                .key(Key.of("Test", APP_ID))
+                .appId(APP_ID)
+                .ingressPoint(cp1)
+                .egressPoint(cp2)
+                .build();
+
+        TunnelId tunnelId = TunnelId.valueOf("virtual tunnel");
+        // Add the intent to tunnelID mapping to the store.
+        manager.store.addTunnelId(virtualIntent, tunnelId);
+        assertEquals("The tunnels size should match.", 1,
+                     manager.store.getTunnelIds(virtualIntent).size());
+
+        // Remove the intent to tunnelID mapping from the store.
+        manager.store.removeTunnelId(virtualIntent, tunnelId);
+        assertTrue("The tunnels should be empty.",
+                   manager.store.getTunnelIds(virtualIntent).isEmpty());
+    }
+
+
+    /**
+     * Method to create the virtual network for {@code tenantIdValue} for further testing.
+     **/
+    private VirtualNetwork setupVirtualNetworkTopology(String tenantIdValue) {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue));
+        VirtualNetwork virtualNetwork =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue));
+
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        VirtualDevice virtualDevice3 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID3);
+        VirtualDevice virtualDevice4 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID4);
+        VirtualDevice virtualDevice5 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID5);
+
+        ConnectPoint cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
+                                  PortNumber.portNumber(1), cp1);
+
+        ConnectPoint cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
+                                  PortNumber.portNumber(2), cp2);
+
+        ConnectPoint cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
+                                  PortNumber.portNumber(3), cp3);
+
+        ConnectPoint cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
+                                  PortNumber.portNumber(4), cp4);
+
+        ConnectPoint cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
+                                  PortNumber.portNumber(5), cp5);
+
+        cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
+                                  PortNumber.portNumber(6), cp6);
+
+        cp7 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(7));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
+                                  PortNumber.portNumber(7), cp7);
+
+        ConnectPoint cp8 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(8));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
+                                  PortNumber.portNumber(8), cp8);
+
+        ConnectPoint cp9 = new ConnectPoint(virtualDevice5.id(), PortNumber.portNumber(9));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice5.id(),
+                                  PortNumber.portNumber(9), cp9);
+
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
+        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
+        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp8, cp9);
+        virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp9, cp8);
+        virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
+
+        topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        topologyProvider = new DefaultVirtualNetworkProvider();
+        try {
+            TestUtils.setField(topologyProvider, "topologyService", topologyService);
+        } catch (TestUtils.TestUtilsException e) {
+            e.printStackTrace();
+        }
+//        topologyProvider.topologyService = topologyService;
+
+        return virtualNetwork;
+    }
+
+    /**
+     * Test the topologyChanged() method.
+     */
+    @Test
+    public void testTopologyChanged() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(tenantIdValue1);
+        VirtualNetworkProviderService providerService =
+                manager.createProviderService(topologyProvider);
+
+        // Initial setup is two clusters of devices/links.
+        assertEquals("The cluster count did not match.", 2,
+                     topologyService.currentTopology().clusterCount());
+
+        // Adding this link will join the two clusters together.
+        List<Event> reasons = new ArrayList<>();
+        VirtualLink link = manager.createVirtualLink(virtualNetwork.id(), cp6, cp7);
+        virtualNetworkManagerStore.updateLink(link, link.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp7, cp6);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+
+        Topology topology = topologyService.currentTopology();
+        providerService.topologyChanged(topologyProvider.getConnectPoints(topology));
+
+        // Validate that all links are still active.
+        manager.getVirtualLinks(virtualNetwork.id()).forEach(virtualLink -> {
+            assertTrue("The virtual link should be active.",
+                       virtualLink.state().equals(Link.State.ACTIVE));
+        });
+
+        virtualNetworkManagerStore.updateLink(link, link.tunnelId(), Link.State.INACTIVE);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.INACTIVE);
+        providerService.topologyChanged(topologyProvider.getConnectPoints(topology));
+
+        // Validate that all links are active again.
+        manager.getVirtualLinks(virtualNetwork.id()).forEach(virtualLink -> {
+            assertTrue("The virtual link should be active.",
+                       virtualLink.state().equals(Link.State.ACTIVE));
+        });
+    }
+
+    /**
+     * Tests that the get() method returns saved service instances.
+     */
+    @Test
+    public void testServiceGetReturnsSavedInstance() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), DeviceService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), LinkService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), TopologyService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), HostService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), PathService.class);
+
+        // extra setup needed for FlowRuleService, PacketService, GroupService, and IntentService
+        VirtualProviderManager virtualProviderManager = new VirtualProviderManager();
+        virtualProviderManager.registerProvider(new DefaultVirtualFlowRuleProvider());
+        virtualProviderManager.registerProvider(new DefaultVirtualPacketProvider());
+        virtualProviderManager.registerProvider(new DefaultVirtualGroupProvider());
+        testDirectory.add(CoreService.class, coreService)
+                .add(VirtualProviderRegistryService.class, virtualProviderManager)
+                .add(EventDeliveryService.class, new TestEventDispatcher())
+                .add(ClusterService.class, new ClusterServiceAdapter())
+                .add(VirtualNetworkFlowRuleStore.class, new SimpleVirtualFlowRuleStore())
+                .add(VirtualNetworkPacketStore.class, new SimpleVirtualPacketStore())
+                .add(VirtualNetworkGroupStore.class, new SimpleVirtualGroupStore())
+                .add(VirtualNetworkIntentStore.class, new SimpleVirtualIntentStore())
+                .add(VirtualNetworkFlowObjectiveStore.class, new SimpleVirtualFlowObjectiveStore());
+
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), FlowRuleService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), FlowObjectiveService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), PacketService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), GroupService.class);
+        validateServiceGetReturnsSavedInstance(virtualNetwork.id(), IntentService.class);
+    }
+
+    /**
+     * Validates that the get() method returns saved service instances.
+     */
+    private <T> void validateServiceGetReturnsSavedInstance(NetworkId networkId,
+                                                            Class<T> serviceClass) {
+        T serviceInstanceFirst = manager.get(networkId, serviceClass);
+        T serviceInstanceSubsequent = manager.get(networkId, serviceClass);
+        assertSame(serviceClass.getSimpleName() +
+                     ": Subsequent get should be same as the first one",
+                     serviceInstanceFirst, serviceInstanceSubsequent);
+    }
+
+    /**
+     * Method to validate that the actual versus expected virtual network events were
+     * received correctly.
+     *
+     * @param types expected virtual network events.
+     */
+    private void validateEvents(Enum... types) {
+        TestTools.assertAfter(100, () -> {
+            int i = 0;
+            assertEquals("wrong events received", types.length, listener.events.size());
+            for (Event event : listener.events) {
+                assertEquals("incorrect event type", types[i], event.type());
+                i++;
+            }
+            listener.events.clear();
+        });
+    }
+
+    /**
+     * Test listener class to receive virtual network events.
+     */
+    private static class TestListener implements VirtualNetworkListener {
+
+        private List<VirtualNetworkEvent> events = Lists.newArrayList();
+
+        @Override
+        public void event(VirtualNetworkEvent event) {
+            events.add(event);
+        }
+
+    }
+
+    /**
+     * Core service test class.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManagerTest.java
new file mode 100644
index 0000000..a08ab5c
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManagerTest.java
@@ -0,0 +1,312 @@
+/*
+ * 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.onosproject.incubator.net.virtual.impl;
+
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Futures;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.DefaultControllerNode;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkMastershipStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualMastershipStore;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.mastership.MastershipTermService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.onosproject.net.MastershipRole.MASTER;
+import static org.onosproject.net.MastershipRole.STANDBY;
+import static org.onosproject.net.MastershipRole.NONE;
+
+public class VirtualNetworkMastershipManagerTest {
+
+    private static final NodeId NID_LOCAL = new NodeId("local");
+    private static final NodeId NID_OTHER = new NodeId("foo");
+    private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
+
+    private static final TenantId TID = TenantId.tenantId("1");
+
+    private static final DeviceId VDID1 = DeviceId.deviceId("foo:vd1");
+    private static final DeviceId VDID2 = DeviceId.deviceId("foo:vd2");
+    private static final DeviceId VDID3 = DeviceId.deviceId("foo:vd3");
+    private static final DeviceId VDID4 = DeviceId.deviceId("foo:vd4");
+
+    private static final NodeId NID1 = NodeId.nodeId("n1");
+    private static final NodeId NID2 = NodeId.nodeId("n2");
+    private static final NodeId NID3 = NodeId.nodeId("n3");
+    private static final NodeId NID4 = NodeId.nodeId("n4");
+
+    private static final ControllerNode CNODE1 =
+            new DefaultControllerNode(NID1, IpAddress.valueOf("127.0.1.1"));
+    private static final ControllerNode CNODE2 =
+            new DefaultControllerNode(NID2, IpAddress.valueOf("127.0.1.2"));
+    private static final ControllerNode CNODE3 =
+            new DefaultControllerNode(NID3, IpAddress.valueOf("127.0.1.3"));
+    private static final ControllerNode CNODE4 =
+            new DefaultControllerNode(NID4, IpAddress.valueOf("127.0.1.4"));
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+
+    private VirtualNetworkMastershipManager mastershipMgr1;
+    private VirtualNetworkMastershipManager mastershipMgr2;
+    protected MastershipService service;
+    private TestClusterService testClusterService;
+    private EventDeliveryService eventDeliveryService;
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        TestUtils.setField(manager, "coreService", coreService);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+
+        SimpleVirtualMastershipStore store = new SimpleVirtualMastershipStore();
+        TestUtils.setField(store, "coreService", coreService);
+        store.activate();
+
+        testClusterService = new TestClusterService();
+
+        ServiceDirectory testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(ClusterService.class, testClusterService)
+                .add(VirtualNetworkMastershipStore.class, store);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        createVnets();
+
+        mastershipMgr1 = new VirtualNetworkMastershipManager(manager, vnet1.id());
+        mastershipMgr2 = new VirtualNetworkMastershipManager(manager, vnet2.id());
+        service = mastershipMgr1;
+    }
+
+    private void createVnets() {
+        manager.registerTenantId(TID);
+
+        vnet1 = manager.createVirtualNetwork(TID);
+        manager.createVirtualDevice(vnet1.id(), VDID1);
+        manager.createVirtualDevice(vnet1.id(), VDID2);
+
+        vnet2 = manager.createVirtualNetwork(TID);
+        manager.createVirtualDevice(vnet2.id(), VDID3);
+        manager.createVirtualDevice(vnet2.id(), VDID4);
+    }
+
+    @After
+    public void tearDown() {
+        manager.deactivate();
+        virtualNetworkManagerStore.deactivate();
+    }
+
+    @Test
+    public void setRole() {
+        mastershipMgr1.setRole(NID_OTHER, VDID1, MASTER);
+        assertEquals("wrong local role:", NONE, mastershipMgr1.getLocalRole(VDID1));
+        assertEquals("wrong obtained role:", STANDBY, Futures.getUnchecked(mastershipMgr1.requestRoleFor(VDID1)));
+
+        //set to master
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        assertEquals("wrong local role:", MASTER, mastershipMgr1.getLocalRole(VDID1));
+    }
+
+    @Test
+    public void relinquishMastership() {
+        //no backups - should just turn to NONE for device.
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        assertEquals("wrong role:", MASTER, mastershipMgr1.getLocalRole(VDID1));
+        mastershipMgr1.relinquishMastership(VDID1);
+        assertNull("wrong master:", mastershipMgr1.getMasterFor(VDID2));
+        assertEquals("wrong role:", NONE, mastershipMgr1.getLocalRole(VDID1));
+
+        //not master, nothing should happen
+        mastershipMgr1.setRole(NID_LOCAL, VDID2, NONE);
+        mastershipMgr1.relinquishMastership(VDID2);
+        assertNull("wrong role:", mastershipMgr1.getMasterFor(VDID2));
+
+        //provide NID_OTHER as backup and relinquish
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID1));
+        mastershipMgr1.setRole(NID_OTHER, VDID1, STANDBY);
+        mastershipMgr1.relinquishMastership(VDID1);
+        assertEquals("wrong master:", NID_OTHER, mastershipMgr1.getMasterFor(VDID1));
+    }
+
+    @Test
+    public void requestRoleFor() {
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        mastershipMgr1.setRole(NID_OTHER, VDID2, MASTER);
+
+        //local should be master for one but standby for other
+        assertEquals("wrong role:", MASTER, Futures.getUnchecked(mastershipMgr1.requestRoleFor(VDID1)));
+        assertEquals("wrong role:", STANDBY, Futures.getUnchecked(mastershipMgr1.requestRoleFor(VDID2)));
+    }
+
+    @Test
+    public void getMasterFor() {
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        mastershipMgr1.setRole(NID_OTHER, VDID2, MASTER);
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID1));
+        assertEquals("wrong master:", NID_OTHER, mastershipMgr1.getMasterFor(VDID2));
+
+        //have NID_OTHER hand over VDID2 to NID_LOCAL
+        mastershipMgr1.setRole(NID_LOCAL, VDID2, MASTER);
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID2));
+    }
+
+    @Test
+    public void getDevicesOf() {
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        mastershipMgr1.setRole(NID_LOCAL, VDID2, STANDBY);
+        assertEquals("should be one device:", 1, mastershipMgr1.getDevicesOf(NID_LOCAL).size());
+        //hand both devices to NID_LOCAL
+        mastershipMgr1.setRole(NID_LOCAL, VDID2, MASTER);
+        assertEquals("should be two devices:", 2, mastershipMgr1.getDevicesOf(NID_LOCAL).size());
+    }
+
+    @Test
+    public void termService() {
+        MastershipTermService ts = mastershipMgr1;
+
+        //term = 1 for both
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        assertEquals("inconsistent term: ", 1,
+                     ts.getMastershipTerm(VDID1).termNumber());
+
+        //hand devices to NID_LOCAL and back: term = 1 + 2
+        mastershipMgr1.setRole(NID_OTHER, VDID1, MASTER);
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        assertEquals("inconsistent terms: ",
+                     3, ts.getMastershipTerm(VDID1).termNumber());
+    }
+
+    @Test
+    public void balanceWithVnets() {
+
+        testClusterService.put(CNODE1, ControllerNode.State.ACTIVE);
+        testClusterService.put(CNODE2, ControllerNode.State.ACTIVE);
+
+        mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+        mastershipMgr1.setRole(NID_LOCAL, VDID2, MASTER);
+        assertEquals("wrong local role:", MASTER, mastershipMgr1.getLocalRole(VDID1));
+        assertEquals("wrong local role:", MASTER, mastershipMgr1.getLocalRole(VDID2));
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID1));
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID2));
+
+        //do balancing according to vnet Id.
+        mastershipMgr1.balanceRoles();
+        assertEquals("wrong master:", NID1, mastershipMgr1.getMasterFor(VDID1));
+        assertEquals("wrong master:", NID1, mastershipMgr1.getMasterFor(VDID2));
+
+        mastershipMgr2.setRole(NID_LOCAL, VDID3, MASTER);
+        mastershipMgr2.setRole(NID_LOCAL, VDID4, MASTER);
+        assertEquals("wrong local role:", MASTER, mastershipMgr2.getLocalRole(VDID3));
+        assertEquals("wrong local role:", MASTER, mastershipMgr2.getLocalRole(VDID4));
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr2.getMasterFor(VDID3));
+        assertEquals("wrong master:", NID_LOCAL, mastershipMgr2.getMasterFor(VDID4));
+
+        //do balancing according to vnet Id.
+        mastershipMgr2.balanceRoles();
+        assertEquals("wrong master:", NID2, mastershipMgr2.getMasterFor(VDID3));
+        assertEquals("wrong master:", NID2, mastershipMgr2.getMasterFor(VDID4));
+
+        // make N1 inactive
+        testClusterService.put(CNODE1, ControllerNode.State.INACTIVE);
+        mastershipMgr1.balanceRoles();
+        assertEquals("wrong master:", NID2, mastershipMgr1.getMasterFor(VDID1));
+        assertEquals("wrong master:", NID2, mastershipMgr1.getMasterFor(VDID2));
+    }
+
+    private final class TestClusterService extends ClusterServiceAdapter {
+
+        final Map<NodeId, ControllerNode> nodes = new HashMap<>();
+        final Map<NodeId, ControllerNode.State> nodeStates = new HashMap<>();
+
+        ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
+
+        @Override
+        public ControllerNode getLocalNode() {
+            return local;
+        }
+
+        @Override
+        public Set<ControllerNode> getNodes() {
+            return Sets.newHashSet(nodes.values());
+        }
+
+        @Override
+        public ControllerNode getNode(NodeId nodeId) {
+            return nodes.get(nodeId);
+        }
+
+        @Override
+        public ControllerNode.State getState(NodeId nodeId) {
+            return nodeStates.get(nodeId);
+        }
+
+        public void put(ControllerNode cn, ControllerNode.State state) {
+            nodes.put(cn.id(), cn);
+            nodeStates.put(cn.id(), state);
+        }
+    }
+
+    private final class TestSimpleMastershipStore extends SimpleVirtualMastershipStore
+            implements VirtualNetworkMastershipStore {
+
+        public TestSimpleMastershipStore(ClusterService clusterService) {
+            super.clusterService = clusterService;
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMeterManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMeterManagerTest.java
new file mode 100644
index 0000000..3eb6e88
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMeterManagerTest.java
@@ -0,0 +1,332 @@
+/*
+ * 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.onosproject.incubator.net.virtual.impl;
+
+import com.google.common.collect.Maps;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onosproject.TestApplicationId;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkMeterStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.event.VirtualListenerRegistryManager;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualMeterProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualMeterProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualMeterStore;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.intent.FakeIntentManager;
+import org.onosproject.net.intent.TestableIntentService;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.DefaultBand;
+import org.onosproject.net.meter.DefaultMeter;
+import org.onosproject.net.meter.DefaultMeterFeatures;
+import org.onosproject.net.meter.DefaultMeterRequest;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterFeaturesKey;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.meter.MeterOperation;
+import org.onosproject.net.meter.MeterOperations;
+import org.onosproject.net.meter.MeterRequest;
+import org.onosproject.net.meter.MeterState;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.*;
+
+/**
+ * Virtual Network meter manager tests.
+ */
+public class VirtualNetworkMeterManagerTest extends VirtualNetworkTestUtil {
+    private static final ProviderId PID = new ProviderId("of", "foo");
+    private static final NodeId NID_LOCAL = new NodeId("local");
+    private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private TestableIntentService intentService = new FakeIntentManager();
+    private ServiceDirectory testDirectory;
+    private VirtualProviderManager providerRegistryService;
+
+    private EventDeliveryService eventDeliveryService;
+    VirtualListenerRegistryManager listenerRegistryManager =
+            VirtualListenerRegistryManager.getInstance();
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private SimpleVirtualMeterStore meterStore;
+
+    private VirtualNetworkMeterManager meterManager1;
+    private VirtualNetworkMeterManager meterManager2;
+
+    private TestProvider provider = new TestProvider();
+    private VirtualMeterProviderService providerService1;
+    private VirtualMeterProviderService providerService2;
+
+    private ApplicationId appId;
+
+    private Meter m1;
+    private Meter m2;
+    private MeterRequest.Builder m1Request;
+    private MeterRequest.Builder m2Request;
+
+    private Map<MeterId, Meter> meters = Maps.newHashMap();
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+        CoreService coreService = new TestCoreService();
+        TestStorageService storageService = new TestStorageService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", storageService);
+        virtualNetworkManagerStore.activate();
+
+        meterStore = new SimpleVirtualMeterStore();
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(provider);
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        TestUtils.setField(manager, "coreService", coreService);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+//        eventDeliveryService.addSink(VirtualEvent.class, listenerRegistryManager);
+
+        appId = new TestApplicationId("MeterManagerTest");
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(StorageService.class, storageService)
+                .add(VirtualNetworkMeterStore.class, meterStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        vnet1 = setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = setupVirtualNetworkTopology(manager, TID2);
+
+        meterManager1 = new VirtualNetworkMeterManager(manager, vnet1.id());
+        meterManager2 = new VirtualNetworkMeterManager(manager, vnet2.id());
+
+        providerService1 = (VirtualMeterProviderService)
+                providerRegistryService.getProviderService(vnet1.id(), VirtualMeterProvider.class);
+        providerService2 = (VirtualMeterProviderService)
+                providerRegistryService.getProviderService(vnet2.id(), VirtualMeterProvider.class);
+
+        assertTrue("provider should be registered",
+                   providerRegistryService.getProviders().contains(provider.id()));
+
+        setupMeterTestVariables();
+    }
+
+    @After
+    public void tearDown() {
+        providerRegistryService.unregisterProvider(provider);
+        assertFalse("provider should not be registered",
+                    providerRegistryService.getProviders().contains(provider.id()));
+
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+
+        virtualNetworkManagerStore.deactivate();
+    }
+
+    /** Test for meter submit(). */
+    @Test
+    public void testAddition() {
+        meterManager1.submit(m1Request.add());
+
+        assertTrue("The meter was not added",
+                   meterManager1.getAllMeters().size() == 1);
+        assertThat(meterManager1.getMeter(VDID1, MeterId.meterId(1)), is(m1));
+
+        assertTrue("The meter shouldn't be added for vnet2",
+                   meterManager2.getAllMeters().size() == 0);
+    }
+
+    /** Test for meter remove(). */
+    @Test
+    public void testRemove() {
+        meterManager1.submit(m1Request.add());
+        meterManager1.withdraw(m1Request.remove(), m1.id());
+
+        assertThat(meterManager1.getMeter(VDID1, MeterId.meterId(1)).state(),
+                   is(MeterState.PENDING_REMOVE));
+
+        providerService1.pushMeterMetrics(m1.deviceId(), Collections.emptyList());
+
+        assertTrue("The meter was not removed", meterManager1.getAllMeters().size() == 0);
+        assertTrue("The meter shouldn't be added for vnet2",
+                   meterManager2.getAllMeters().size() == 0);
+    }
+
+    /** Test for meter submit with multiple devices. */
+    @Test
+    public void testMultipleDevice() {
+        meterManager1.submit(m1Request.add());
+        meterManager1.submit(m2Request.add());
+
+        assertTrue("The meters were not added",
+                   meterManager1.getAllMeters().size() == 2);
+        assertTrue("The meter shouldn't be added for vnet2",
+                   meterManager2.getAllMeters().size() == 0);
+
+        assertThat(meterManager1.getMeter(VDID1, MeterId.meterId(1)), is(m1));
+        assertThat(meterManager1.getMeter(VDID2, MeterId.meterId(1)), is(m2));
+    }
+
+    /** Test for meter features inside store. */
+    @Test
+    public void testMeterFeatures() {
+        //Test for virtual network 1
+        assertEquals(meterStore.getMaxMeters(vnet1.id(),
+                                             MeterFeaturesKey.key(VDID1)), 255L);
+        assertEquals(meterStore.getMaxMeters(vnet1.id(),
+                                             MeterFeaturesKey.key(VDID2)), 2);
+        //Test for virtual network 2
+        assertEquals(meterStore.getMaxMeters(vnet2.id(),
+                                             MeterFeaturesKey.key(VDID1)), 100);
+        assertEquals(meterStore.getMaxMeters(vnet2.id(),
+                                             MeterFeaturesKey.key(VDID2)), 10);
+    }
+
+    /** Set variables such as meters and request required for testing. */
+    private void setupMeterTestVariables() {
+        Band band = DefaultBand.builder()
+                .ofType(Band.Type.DROP)
+                .withRate(500)
+                .build();
+
+        m1 = DefaultMeter.builder()
+                .forDevice(VDID1)
+                .fromApp(appId)
+                .withId(MeterId.meterId(1))
+                .withUnit(Meter.Unit.KB_PER_SEC)
+                .withBands(Collections.singletonList(band))
+                .build();
+
+        m2 = DefaultMeter.builder()
+                .forDevice(VDID2)
+                .fromApp(appId)
+                .withId(MeterId.meterId(1))
+                .withUnit(Meter.Unit.KB_PER_SEC)
+                .withBands(Collections.singletonList(band))
+                .build();
+
+        m1Request = DefaultMeterRequest.builder()
+                .forDevice(VDID1)
+                .fromApp(appId)
+                .withUnit(Meter.Unit.KB_PER_SEC)
+                .withBands(Collections.singletonList(band));
+
+        m2Request = DefaultMeterRequest.builder()
+                .forDevice(VDID2)
+                .fromApp(appId)
+                .withUnit(Meter.Unit.KB_PER_SEC)
+                .withBands(Collections.singletonList(band));
+
+        meterStore.storeMeterFeatures(vnet1.id(),
+                                      DefaultMeterFeatures.builder().forDevice(VDID1)
+                                              .withMaxMeters(255L)
+                                              .withBandTypes(new HashSet<>())
+                                              .withUnits(new HashSet<>())
+                                              .hasStats(false)
+                                              .hasBurst(false)
+                                              .withMaxBands((byte) 0)
+                                              .withMaxColors((byte) 0)
+                                              .build());
+        meterStore.storeMeterFeatures(vnet1.id(),
+                                      DefaultMeterFeatures.builder().forDevice(VDID2)
+                                              .withMaxMeters(2)
+                                              .withBandTypes(new HashSet<>())
+                                              .withUnits(new HashSet<>())
+                                              .hasBurst(false)
+                                              .hasStats(false)
+                                              .withMaxBands((byte) 0)
+                                              .withMaxColors((byte) 0)
+                                              .build());
+
+        meterStore.storeMeterFeatures(vnet2.id(),
+                                      DefaultMeterFeatures.builder().forDevice(VDID1)
+                                              .withMaxMeters(100L)
+                                              .withBandTypes(new HashSet<>())
+                                              .withUnits(new HashSet<>())
+                                              .hasStats(false)
+                                              .hasBurst(false)
+                                              .withMaxBands((byte) 0)
+                                              .withMaxColors((byte) 0)
+                                              .build());
+        meterStore.storeMeterFeatures(vnet2.id(),
+                                      DefaultMeterFeatures.builder().forDevice(VDID2)
+                                              .withMaxMeters(10)
+                                              .withBandTypes(new HashSet<>())
+                                              .withUnits(new HashSet<>())
+                                              .hasBurst(false)
+                                              .hasStats(false)
+                                              .withMaxBands((byte) 0)
+                                              .withMaxColors((byte) 0)
+                                              .build());
+    }
+
+    private class TestProvider
+            extends AbstractVirtualProvider
+            implements VirtualMeterProvider {
+
+        protected TestProvider() {
+            super(PID);
+        }
+
+        @Override
+        public void performMeterOperation(NetworkId networkId, DeviceId deviceId,
+                                          MeterOperations meterOps) {
+
+        }
+
+        @Override
+        public void performMeterOperation(NetworkId networkId, DeviceId deviceId,
+                                          MeterOperation meterOp) {
+            meters.put(meterOp.meter().id(), meterOp.meter());
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerTest.java
new file mode 100644
index 0000000..66ccb73
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerTest.java
@@ -0,0 +1,416 @@
+/*
+ * 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.onosproject.incubator.net.virtual.impl;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.TestApplicationId;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkPacketStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualPacketProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualFlowRuleStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualPacketStore;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.*;
+import static org.onosproject.net.flowobjective.Objective.Operation.ADD;
+import static org.onosproject.net.flowobjective.Objective.Operation.REMOVE;
+import static org.onosproject.net.packet.PacketPriority.CONTROL;
+import static org.onosproject.net.packet.PacketPriority.REACTIVE;
+
+/**
+ * Junit tests for VirtualNetworkPacketManager using SimpleVirtualPacketStore.
+ */
+public class VirtualNetworkPacketManagerTest extends VirtualNetworkTestUtil {
+
+    private static final int PROCESSOR_PRIORITY = 1;
+
+    protected VirtualNetworkManager manager;
+    protected DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService = new TestCoreService();
+    protected TestServiceDirectory testDirectory;
+    private EventDeliveryService eventDeliveryService;
+    private VirtualProviderManager providerRegistryService;
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private VirtualPacketProvider provider = new TestPacketProvider();
+    protected VirtualNetworkPacketStore packetStore = new SimpleVirtualPacketStore();
+
+    protected VirtualNetworkPacketManager packetManager1;
+    private VirtualNetworkPacketManager packetManager2;
+
+    private ApplicationId appId = new TestApplicationId("VirtualPacketManagerTest");
+
+    private VirtualFlowRuleProvider flowRuleProvider = new TestFlowRuleProvider();
+    private SimpleVirtualFlowRuleStore flowRuleStore;
+    private SimpleVirtualFlowObjectiveStore flowObjectiveStore;
+    protected StorageService storageService = new TestStorageService();
+
+    @Before
+    public void setUp() throws TestUtils.TestUtilsException {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", storageService);
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        flowObjectiveStore = new SimpleVirtualFlowObjectiveStore();
+        TestUtils.setField(flowObjectiveStore, "storageService", storageService);
+        flowObjectiveStore.activate();
+        flowRuleStore = new SimpleVirtualFlowRuleStore();
+        flowRuleStore.activate();
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(provider);
+        providerRegistryService.registerProvider(flowRuleProvider);
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(ClusterService.class, new ClusterServiceAdapter())
+                .add(VirtualNetworkFlowRuleStore.class, flowRuleStore)
+                .add(VirtualNetworkFlowObjectiveStore.class, flowObjectiveStore)
+                .add(VirtualNetworkPacketStore.class, packetStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+
+        manager.activate();
+
+        vnet1 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID2);
+
+        packetManager1 = new VirtualNetworkPacketManager(manager, vnet1.id());
+        packetManager2 = new VirtualNetworkPacketManager(manager, vnet2.id());
+    }
+
+    /**
+     * Tests the correct usage of addProcessor() for a outbound packet.
+     */
+    @Test
+    public void addProcessorTest() {
+        PacketProcessor testProcessor = new TestProcessor();
+        packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
+
+        assertEquals("1 processor expected", 1,
+                    packetManager1.getProcessors().size());
+        assertEquals("0 processor expected", 0,
+                     packetManager2.getProcessors().size());
+
+        assertEquals("not equal packet processor", testProcessor,
+                     packetManager1.getProcessors().get(0).processor());
+        assertEquals("not equal packet processor priority", PROCESSOR_PRIORITY,
+                     packetManager1.getProcessors().get(0).priority());
+    }
+
+    /**
+     * Tests the correct usage of addProcessor() for a outbound packet.
+     */
+    @Test
+    public void removeProcessorTest() {
+        PacketProcessor testProcessor = new TestProcessor();
+        packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
+
+        assertEquals("1 processor expected", 1,
+                     packetManager1.getProcessors().size());
+        assertEquals("0 processor expected", 0,
+                     packetManager2.getProcessors().size());
+
+        packetManager1.removeProcessor(testProcessor);
+
+        assertEquals("0 processor expected", 0,
+                     packetManager1.getProcessors().size());
+        assertEquals("0 processor expected", 0,
+                     packetManager2.getProcessors().size());
+    }
+
+    /**
+     * Tests the correct usage of emit() for a outbound packet.
+     */
+    @Test
+    public void emitTest() {
+        OutboundPacket packet =
+                new DefaultOutboundPacket(VDID1, DefaultTrafficTreatment.emptyTreatment(), ByteBuffer.allocate(5));
+        packetManager1.emit(packet);
+        assertEquals("Packet not emitted correctly", packet, emittedPacket);
+    }
+
+    /**
+     * Tests the addition and removal of packet requests for a device.
+     *
+     * @throws TestUtils.TestUtilsException
+     */
+    @Test
+    public void requestAndCancelPacketsForDeviceTest() throws TestUtils.TestUtilsException {
+        TestFlowObjectiveService testFlowObjectiveService = new TestFlowObjectiveService();
+        TestUtils.setField(packetManager1, "objectiveService", testFlowObjectiveService);
+        TrafficSelector ts = DefaultTrafficSelector.emptySelector();
+        Optional<DeviceId> optionalDeviceId = Optional.of(VDID3);
+
+        // add first request
+        packetManager1.requestPackets(ts, CONTROL, appId, optionalDeviceId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, ADD);
+
+        // add same request as first
+        packetManager1.requestPackets(ts, CONTROL, appId, optionalDeviceId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, ADD);
+
+        // add second request
+        packetManager1.requestPackets(ts, REACTIVE, appId, optionalDeviceId);
+        assertEquals("2 packets expected", 2, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, ADD);
+
+        // cancel second request
+        packetManager1.cancelPackets(ts, REACTIVE, appId, optionalDeviceId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, REMOVE);
+
+        // cancel second request again
+        packetManager1.cancelPackets(ts, REACTIVE, appId, optionalDeviceId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, REMOVE);
+
+        // cancel first request
+        packetManager1.cancelPackets(ts, CONTROL, appId, optionalDeviceId);
+        assertEquals("0 packet expected", 0, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, REMOVE);
+    }
+
+    /**
+     * Tests the addition and removal of packet requests for all devices in a virtual
+     * network.
+     *
+     * @throws TestUtils.TestUtilsException
+     */
+    @Test
+    public void requestAndCancelPacketsForVnetTest() throws TestUtils.TestUtilsException {
+        TestFlowObjectiveService testFlowObjectiveService = new TestFlowObjectiveService();
+        TestUtils.setField(packetManager1, "objectiveService", testFlowObjectiveService);
+        TrafficSelector ts = DefaultTrafficSelector.emptySelector();
+        Set<VirtualDevice> vnet1Devices = manager.getVirtualDevices(vnet1.id());
+
+        // add first request
+        packetManager1.requestPackets(ts, CONTROL, appId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, ADD);
+
+        // add same request as first
+        packetManager1.requestPackets(ts, CONTROL, appId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, ADD);
+
+        // add second request
+        packetManager1.requestPackets(ts, REACTIVE, appId);
+        assertEquals("2 packets expected", 2, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, ADD);
+
+        // cancel second request
+        packetManager1.cancelPackets(ts, REACTIVE, appId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, REMOVE);
+
+        // cancel second request again
+        packetManager1.cancelPackets(ts, REACTIVE, appId);
+        assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, REMOVE);
+
+        // cancel first request
+        packetManager1.cancelPackets(ts, CONTROL, appId);
+        assertEquals("0 packet expected", 0, packetManager1.getRequests().size());
+        testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, REMOVE);
+    }
+
+    protected OutboundPacket emittedPacket = null;
+
+    /**
+     * Core service test class.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return appId;
+        }
+    }
+
+    private class TestPacketProvider extends AbstractVirtualProvider
+            implements VirtualPacketProvider {
+
+        /**
+         * Creates a provider with the supplied identifier.
+         */
+        protected TestPacketProvider() {
+            super(new ProviderId("test-packet",
+                                 "org.onosproject.virtual.test-packet"));
+        }
+
+        @Override
+        public void emit(NetworkId networkId, OutboundPacket packet) {
+            emittedPacket = packet;
+        }
+
+    }
+
+    private class TestProcessor implements PacketProcessor {
+
+        @Override
+        public void process(PacketContext context) {
+
+        }
+    }
+
+    private class TestFlowObjectiveService extends FlowObjectiveServiceAdapter {
+        // track objectives received for each device
+        private final Map<DeviceId, Set<ForwardingObjective>> deviceFwdObjs = new HashMap<>();
+
+        @Override
+        public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
+            deviceFwdObjs.compute(deviceId, (deviceId1, forwardingObjectives) -> {
+                        if (forwardingObjectives == null) {
+                            return Sets.newHashSet(forwardingObjective);
+                        }
+                        forwardingObjectives.add(forwardingObjective);
+                        return forwardingObjectives;
+                    }
+            );
+        }
+
+        private void validateObjectives(Set<VirtualDevice> vdevs, TrafficSelector ts,
+                                    PacketPriority pp, Objective.Operation op) {
+            assertNotNull("set of devices must not be null", vdevs);
+            for (VirtualDevice vdev: vdevs) {
+                assertTrue("Forwarding objective must exist for device " + vdev.id(),
+                           deviceHasObjective(vdev.id(), ts, pp, op));
+            }
+        }
+
+        private void validateObjectiveForDevice(DeviceId deviceId, TrafficSelector ts,
+                                    PacketPriority pp, Objective.Operation op) {
+            assertNotNull("deviceId must not be null", deviceId);
+            assertTrue("Forwarding objective must exist for device " + deviceId,
+                           deviceHasObjective(deviceId, ts, pp, op));
+        }
+
+        private boolean deviceHasObjective(DeviceId deviceId, TrafficSelector ts,
+                                   PacketPriority pp, Objective.Operation op) {
+            Set<ForwardingObjective> fos = deviceFwdObjs.get(deviceId);
+            if (fos != null) {
+                for (ForwardingObjective fo: fos) {
+                    if (fo.selector().equals(ts)
+                            && fo.priority() == pp.priorityValue()
+                            && fo.op().equals(op)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    private class TestFlowRuleProvider extends AbstractVirtualProvider
+            implements VirtualFlowRuleProvider {
+
+        protected TestFlowRuleProvider() {
+            super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
+        }
+
+        @Override
+        public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
+
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerWithDistStoreTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerWithDistStoreTest.java
new file mode 100644
index 0000000..914d709
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerWithDistStoreTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.onosproject.incubator.net.virtual.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ComponentContextAdapter;
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualPacketStore;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
+import org.onosproject.store.cluster.messaging.MessageSubject;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
+
+import static org.junit.Assert.assertNull;
+
+/**
+ * Junit tests for VirtualNetworkPacketManager using DistributedVirtualPacketStore..
+ * This test class extends VirtualNetworkPacketManagerTest - all the tests defined in
+ * VirtualNetworkPacketManagerTest will run using DistributedVirtualPacketStore.
+ */
+public class VirtualNetworkPacketManagerWithDistStoreTest extends VirtualNetworkPacketManagerTest {
+
+    private DistributedVirtualPacketStore distStore;
+    private ClusterService clusterService = new ClusterServiceAdapter();
+
+    @Before
+    public void setUp() throws TestUtils.TestUtilsException {
+        setUpDistPacketStore();
+        super.setUp();
+        TestUtils.setField(packetManager1, "storageService", storageService);
+    }
+
+    private void setUpDistPacketStore() throws TestUtils.TestUtilsException {
+        distStore = new DistributedVirtualPacketStore();
+        TestUtils.setField(distStore, "cfgService", new ComponentConfigAdapter());
+        TestUtils.setField(distStore, "storageService", storageService);
+        TestUtils.setField(distStore, "clusterService", clusterService);
+        TestUtils.setField(distStore, "communicationService", new TestClusterCommunicationService());
+        TestUtils.setField(distStore, "mastershipService", new TestMastershipService());
+
+        distStore.activate(new ComponentContextAdapter());
+        packetStore = distStore; // super.setUp() will cause Distributed store to be used.
+    }
+
+    @After
+    public void tearDown() {
+        distStore.deactivate();
+    }
+
+    @Override
+    @Test
+    @Ignore("Ignore until there is MastershipService support for virtual devices")
+    public void emitTest() {
+        super.emitTest();
+    }
+
+    /**
+     * Tests the correct usage of emit() for a outbound packet - master of packet's
+     * sendThrough is not local node.
+     */
+    @Test
+    @Ignore("Ignore until there is MastershipService support for virtual devices")
+    public void emit2Test() {
+        OutboundPacket packet =
+                new DefaultOutboundPacket(VDID2, DefaultTrafficTreatment.emptyTreatment(), ByteBuffer.allocate(5));
+        packetManager1.emit(packet);
+        assertNull("Packet should not have been emmitted", emittedPacket);
+    }
+
+    private final class TestMastershipService extends MastershipServiceAdapter {
+        @Override
+        public NodeId getMasterFor(DeviceId deviceId) {
+            if (VDID1.equals(deviceId)) {
+                return clusterService.getLocalNode().id();
+            }
+            return new NodeId("abc");
+        }
+    }
+
+    private final class TestClusterCommunicationService extends ClusterCommunicationServiceAdapter {
+        @Override
+        public <M> CompletableFuture<Void> unicast(M message, MessageSubject subject,
+                                                   Function<M, byte[]> encoder, NodeId toNodeId) {
+            return new CompletableFuture<>();
+        }
+    }
+
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManagerTest.java
new file mode 100644
index 0000000..b8db7ea
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManagerTest.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.graph.ScalarWeight;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.ElementId;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+import org.onosproject.net.topology.LinkWeigher;
+import org.onosproject.net.topology.LinkWeigherAdapter;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Junit tests for VirtualNetworkPathService.
+ */
+public class VirtualNetworkPathManagerTest extends TestDeviceParams {
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+
+    private TestServiceDirectory testDirectory;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+    }
+
+    /**
+     * Sets up an empty virtual network (no devices, links).
+     *
+     * @return virtual network
+     */
+    private VirtualNetwork setupEmptyVnet() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        return manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+    }
+
+    /**
+     * Creates a virtual network for further testing.
+     *
+     * @return virtual network
+     */
+    private VirtualNetwork setupVnet() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        VirtualDevice virtualDevice3 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID3);
+        VirtualDevice virtualDevice4 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID4);
+
+        ConnectPoint cp11 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice1, 1);
+        ConnectPoint cp12 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice1, 2);
+        ConnectPoint cp23 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice2, 3);
+        ConnectPoint cp24 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice2, 4);
+        ConnectPoint cp35 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice3, 5);
+        ConnectPoint cp36 = createConnectPointAndVirtualPort(virtualNetwork, virtualDevice3, 6);
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp11, cp23);
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp23, cp11);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp24, cp35);
+        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp35, cp24);
+        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp12, cp36);
+        virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp36, cp12);
+        virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
+
+        return virtualNetwork;
+    }
+
+    /**
+     * Creates a connect point and related virtual port.
+     *
+     * @param vnet virtual network
+     * @param vDev virtual device
+     * @param portNumber port number
+     * @return connect point
+     */
+    private ConnectPoint createConnectPointAndVirtualPort(
+            VirtualNetwork vnet, VirtualDevice vDev, long portNumber) {
+        ConnectPoint cp = new ConnectPoint(vDev.id(), PortNumber.portNumber(portNumber));
+        manager.createVirtualPort(vnet.id(), cp.deviceId(), cp.port(),
+                                  new ConnectPoint(vDev.id(), cp.port()));
+        return cp;
+    }
+
+    /**
+     * Tests getPaths(), getDisjointPaths()
+     * on a non-empty virtual network.
+     */
+    @Test
+    public void testGetPathsOnNonEmptyVnet() {
+        VirtualNetwork vnet = setupVnet();
+        PathService pathService = manager.get(vnet.id(), PathService.class);
+
+        // src and dest are in vnet and are connected by a virtual link
+        Set<Path> paths = pathService.getPaths(DID1, DID3);
+        validatePaths(paths, 1, 1, DID1, DID3, 1.0);
+
+        LinkWeigher linkWeight = new LinkWeigherAdapter(2.0);
+        paths = pathService.getPaths(DID1, DID3, linkWeight);
+        validatePaths(paths, 1, 1, DID1, DID3, 2.0);
+
+        Set<DisjointPath> disjointPaths = pathService.getDisjointPaths(DID1, DID3);
+        validatePaths(disjointPaths, 1, 1, DID1, DID3, 1.0);
+
+        disjointPaths = pathService.getDisjointPaths(DID1, DID3, linkWeight);
+        validatePaths(disjointPaths, 1, 1, DID1, DID3, 2.0);
+
+        // src and dest are in vnet but are not connected
+        paths = pathService.getPaths(DID4, DID3);
+        assertEquals("incorrect path count", 0, paths.size());
+
+        disjointPaths = pathService.getDisjointPaths(DID4, DID3);
+        assertEquals("incorrect path count", 0, disjointPaths.size());
+
+        // src is in vnet, but dest is not in vnet.
+        DeviceId nonExistentDeviceId = DeviceId.deviceId("nonExistentDevice");
+        paths = pathService.getPaths(DID2, nonExistentDeviceId);
+        assertEquals("incorrect path count", 0, paths.size());
+
+        disjointPaths = pathService.getDisjointPaths(DID2, nonExistentDeviceId);
+        assertEquals("incorrect path count", 0, disjointPaths.size());
+    }
+
+    /**
+     * Tests getPaths(), getDisjointPaths()
+     * on an empty virtual network.
+     */
+    @Test
+    public void testGetPathsOnEmptyVnet() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        PathService pathService = manager.get(vnet.id(), PathService.class);
+
+        Set<Path> paths = pathService.getPaths(DID1, DID3);
+        assertEquals("incorrect path count", 0, paths.size());
+
+        Set<DisjointPath> disjointPaths = pathService.getDisjointPaths(DID1, DID3);
+        assertEquals("incorrect path count", 0, disjointPaths.size());
+    }
+
+    /**
+     * Tests getPaths() using a null source device on an empty virtual network.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPathsWithNullSrc() {
+        VirtualNetwork vnet = setupEmptyVnet();
+        PathService pathService = manager.get(vnet.id(), PathService.class);
+        pathService.getPaths(null, DID3);
+    }
+
+    /**
+     * Tests getPaths() using a null destination device on a non-empty virtual network.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPathsWithNullDest() {
+        VirtualNetwork vnet = setupVnet();
+        PathService pathService = manager.get(vnet.id(), PathService.class);
+        pathService.getPaths(DID1, null);
+    }
+
+
+    // Makes sure the set of paths meets basic expectations.
+    private void validatePaths(Set<? extends Path> paths, int count, int length,
+                               ElementId src, ElementId dst, double cost) {
+        assertEquals("incorrect path count", count, paths.size());
+        for (Path path : paths) {
+            assertEquals("incorrect length", length, path.links().size());
+            assertEquals("incorrect source", src, path.src().elementId());
+            assertEquals("incorrect destination", dst, path.dst().elementId());
+            assertEquals("incorrect cost", ScalarWeight.toWeight(cost), path.weight());
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTestUtil.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTestUtil.java
new file mode 100644
index 0000000..d1b7274
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTestUtil.java
@@ -0,0 +1,107 @@
+/*
+ * 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.onosproject.incubator.net.virtual.impl;
+
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+
+import static org.onosproject.net.DeviceId.deviceId;
+
+public class VirtualNetworkTestUtil extends TestDeviceParams {
+
+    protected static final TenantId TID1 = TenantId.tenantId("tid1");
+    protected static final TenantId TID2 = TenantId.tenantId("tid2");
+
+    protected static final DeviceId VDID1 = deviceId("of:foo_v");
+    protected static final DeviceId VDID2 = deviceId("of:bar_v");
+    protected static final DeviceId VDID3 = deviceId("of:who_v");
+    protected static final DeviceId VDID4 = deviceId("of:what_v");
+
+    protected static final DeviceId PHYDID1 = deviceId("physical:1");
+    protected static final DeviceId PHYDID2 = deviceId("physical:2");
+    protected static final DeviceId PHYDID3 = deviceId("physical:3");
+    protected static final DeviceId PHYDID4 = deviceId("physical:4");
+
+    /**
+     * Method to create the virtual network for further testing.
+     *
+     * @return virtual network
+     */
+    public static VirtualNetwork setupVirtualNetworkTopology(VirtualNetworkManager manager,
+                                                             TenantId tenantId) {
+        manager.registerTenantId(tenantId);
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(tenantId);
+
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID2);
+        VirtualDevice virtualDevice3 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID3);
+        VirtualDevice virtualDevice4 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID4);
+
+        ConnectPoint vcp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
+        ConnectPoint cp1 = new ConnectPoint(DID1, PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), vcp1.deviceId(), vcp1.port(), cp1);
+
+        ConnectPoint vcp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
+        ConnectPoint cp2 = new ConnectPoint(DID1, PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), vcp2.deviceId(), vcp2.port(), cp2);
+
+        ConnectPoint vcp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
+        ConnectPoint cp3 = new ConnectPoint(DID2, PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), vcp3.deviceId(), vcp3.port(), cp3);
+
+        ConnectPoint vcp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
+        ConnectPoint cp4 = new ConnectPoint(DID2, PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), vcp4.deviceId(), vcp4.port(), cp4);
+
+        ConnectPoint vcp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
+        ConnectPoint cp5 = new ConnectPoint(DID3, PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), vcp5.deviceId(), vcp5.port(), cp5);
+
+        ConnectPoint vcp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
+        ConnectPoint cp6 = new ConnectPoint(DID3, PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), vcp6.deviceId(), vcp6.port(), cp6);
+
+        DistributedVirtualNetworkStore virtualNetworkManagerStore =
+                (DistributedVirtualNetworkStore) manager.store;
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), vcp1, vcp3);
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), vcp3, vcp1);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), vcp4, vcp5);
+        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), vcp5, vcp4);
+        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), vcp2, vcp6);
+        virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), vcp6, vcp2);
+        virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
+
+        return virtualNetwork;
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManagerTest.java
new file mode 100644
index 0000000..8fb7904
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManagerTest.java
@@ -0,0 +1,642 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.graph.ScalarWeight;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+import org.onosproject.net.topology.LinkWeigher;
+import org.onosproject.net.topology.LinkWeigherAdapter;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyCluster;
+import org.onosproject.net.topology.TopologyService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Junit tests for VirtualNetworkTopologyService.
+ */
+public class VirtualNetworkTopologyManagerTest extends TestDeviceParams {
+
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService;
+    private TestServiceDirectory testDirectory;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+        coreService = new VirtualNetworkTopologyManagerTest.TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+    }
+
+    /**
+     * Method to create the virtual network for further testing.
+     *
+     * @return virtual network
+     */
+    private VirtualNetwork setupVirtualNetworkTopology() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        VirtualDevice virtualDevice3 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID3);
+        VirtualDevice virtualDevice4 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID4);
+
+        ConnectPoint cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), cp1.deviceId(), cp1.port(), cp1);
+
+        ConnectPoint cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), cp2.deviceId(), cp2.port(), cp2);
+
+        ConnectPoint cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
+        manager.createVirtualPort(virtualNetwork.id(), cp3.deviceId(), cp3.port(), cp3);
+
+        ConnectPoint cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
+        manager.createVirtualPort(virtualNetwork.id(), cp4.deviceId(), cp4.port(), cp4);
+
+        ConnectPoint cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
+        manager.createVirtualPort(virtualNetwork.id(), cp5.deviceId(), cp5.port(), cp5);
+
+        ConnectPoint cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
+        manager.createVirtualPort(virtualNetwork.id(), cp6.deviceId(), cp6.port(), cp6);
+
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
+        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
+        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp2, cp6);
+        virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp6, cp2);
+        virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
+
+        return virtualNetwork;
+    }
+
+    /**
+     * Tests the currentTopology() method.
+     */
+    @Test
+    public void testCurrentTopology() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+        assertNotNull("The topology should not be null.", topology);
+    }
+
+    /**
+     * Test isLatest() method using a null topology.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsLatestByNullTopology() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+
+        // test the isLatest() method with a null topology.
+        topologyService.isLatest(null);
+    }
+
+    /**
+     * Test isLatest() method.
+     */
+    @Test
+    public void testIsLatest() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        // test the isLatest() method.
+        assertTrue("This should be latest topology", topologyService.isLatest(topology));
+
+        VirtualDevice srcVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the isLatest() method where a new device has been added to the current topology.
+        assertFalse("This should not be latest topology", topologyService.isLatest(topology));
+
+        topology = topologyService.currentTopology();
+        ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), src.deviceId(), src.port(),
+                                  new ConnectPoint(srcVirtualDevice.id(), src.port()));
+
+        ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), dst.deviceId(), dst.port(),
+                                  new ConnectPoint(dstVirtualDevice.id(), dst.port()));
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), src, dst);
+
+        // test the isLatest() method where a new link has been added to the current topology.
+        assertFalse("This should not be latest topology", topologyService.isLatest(topology));
+    }
+
+    /**
+     * Test getGraph() method.
+     */
+    @Test
+    public void testGetGraph() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        // test the getGraph() method.
+        assertNotNull("The graph should not be null.", topologyService.getGraph(topology));
+    }
+
+    /**
+     * Test getClusters() method.
+     */
+    @Test
+    public void testGetClusters() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+
+        Topology topology = topologyService.currentTopology();
+
+        // test the getClusters() method.
+        assertNotNull("The clusters should not be null.", topologyService.getClusters(topology));
+        assertEquals("The clusters size did not match.", 2, topologyService.getClusters(topology).size());
+    }
+
+    /**
+     * Test getCluster() method using a null cluster identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetClusterUsingNullClusterId() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        Set<TopologyCluster> clusters = topologyService.getClusters(topology);
+        TopologyCluster cluster = clusters.stream().findFirst().get();
+
+        // test the getCluster() method with a null cluster identifier
+        TopologyCluster cluster1 = topologyService.getCluster(topology, null);
+    }
+
+    /**
+     * Test getCluster() method.
+     */
+    @Test
+    public void testGetCluster() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        Set<TopologyCluster> clusters = topologyService.getClusters(topology);
+        assertNotNull("The clusters should not be null.", clusters);
+        assertEquals("The clusters size did not match.", 2, clusters.size());
+
+        // test the getCluster() method.
+        TopologyCluster cluster = clusters.stream().findFirst().get();
+        assertNotNull("The cluster should not be null.", cluster);
+        TopologyCluster cluster1 = topologyService.getCluster(topology, cluster.id());
+        assertNotNull("The cluster should not be null.", cluster1);
+        assertEquals("The cluster ID did not match.", cluster.id(), cluster1.id());
+    }
+
+    /**
+     * Test getClusterDevices() methods with a null cluster.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetClusterDevicesUsingNullCluster() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+        Set<TopologyCluster> clusters = topologyService.getClusters(topology);
+
+        // test the getClusterDevices() method using a null cluster.
+        Object[] objects = clusters.stream().toArray();
+        assertNotNull("The cluster should not be null.", objects);
+        Set<DeviceId> clusterDevices = topologyService.getClusterDevices(topology, null);
+    }
+
+    /**
+     * Test getClusterLinks() methods with a null cluster.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetClusterLinksUsingNullCluster() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+        Set<TopologyCluster> clusters = topologyService.getClusters(topology);
+
+        // test the getClusterLinks() method using a null cluster.
+        Object[] objects = clusters.stream().toArray();
+        assertNotNull("The cluster should not be null.", objects);
+        Set<Link> clusterLinks = topologyService.getClusterLinks(topology, null);
+    }
+
+    /**
+     * Test getClusterDevices() and getClusterLinks() methods.
+     */
+    @Test
+    public void testGetClusterDevicesLinks() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        Set<TopologyCluster> clusters = topologyService.getClusters(topology);
+        assertNotNull("The clusters should not be null.", clusters);
+        assertEquals("The clusters size did not match.", 2, clusters.size());
+
+        // test the getClusterDevices() method.
+        Object[] objects = clusters.stream().toArray();
+        assertNotNull("The cluster should not be null.", objects);
+        Set<DeviceId> clusterDevices = topologyService.getClusterDevices(topology, (TopologyCluster) objects[0]);
+        assertNotNull("The devices should not be null.", clusterDevices);
+        assertEquals("The devices size did not match.", 3, clusterDevices.size());
+        Set<DeviceId> clusterDevices1 = topologyService.getClusterDevices(topology, (TopologyCluster) objects[1]);
+        assertNotNull("The devices should not be null.", clusterDevices1);
+        assertEquals("The devices size did not match.", 1, clusterDevices1.size());
+
+        // test the getClusterLinks() method.
+        Set<Link> clusterLinks = topologyService.getClusterLinks(topology, (TopologyCluster) objects[0]);
+        assertNotNull("The links should not be null.", clusterLinks);
+        assertEquals("The links size did not match.", 6, clusterLinks.size());
+        Set<Link> clusterLinks1 = topologyService.getClusterLinks(topology, (TopologyCluster) objects[1]);
+        assertNotNull("The links should not be null.", clusterLinks1);
+        assertEquals("The links size did not match.", 0, clusterLinks1.size());
+    }
+
+    /**
+     * Test getPaths() method using a null src device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPathsUsingNullSrcDeviceId() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getPaths() method using a null src device identifier.
+        Set<Path> paths = topologyService.getPaths(topology, null, dstVirtualDevice.id());
+    }
+
+    /**
+     * Test getPaths() method using a null dst device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPathsUsingNullDstDeviceId() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getPaths() method using a null dst device identifier.
+        Set<Path> paths = topologyService.getPaths(topology, srcVirtualDevice.id(), null);
+    }
+
+    /**
+     * Test getPaths() method using a null weight.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetPathsUsingNullWeight() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getPaths() method using a null weight.
+        Set<Path> paths = topologyService.getPaths(topology, srcVirtualDevice.id(),
+                dstVirtualDevice.id(), (LinkWeigher) null);
+    }
+
+    /**
+     * Test getPaths() and getPaths() by weight methods.
+     */
+    @Test
+    public void testGetPaths() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getPaths() method.
+        Set<Path> paths = topologyService.getPaths(topology, srcVirtualDevice.id(), dstVirtualDevice.id());
+        assertNotNull("The paths should not be null.", paths);
+        assertEquals("The paths size did not match.", 1, paths.size());
+
+        // test the getPaths() by weight method.
+        LinkWeigher weight = new LinkWeigherAdapter(1.0);
+        Set<Path> paths1 = topologyService.getPaths(topology, srcVirtualDevice.id(), dstVirtualDevice.id(), weight);
+        assertNotNull("The paths should not be null.", paths1);
+        assertEquals("The paths size did not match.", 1, paths1.size());
+        Path path = paths1.iterator().next();
+        assertEquals("wrong path length", 1, path.links().size());
+        assertEquals("wrong path cost", ScalarWeight.toWeight(1.0), path.weight());
+    }
+
+    /**
+     * Test getDisjointPaths() methods using a null src device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDisjointPathsUsingNullSrcDeviceId() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getDisjointPaths() method using a null src device identifier.
+        Set<DisjointPath> paths = topologyService.getDisjointPaths(topology, null, dstVirtualDevice.id());
+    }
+
+    /**
+     * Test getDisjointPaths() methods using a null dst device identifier.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDisjointPathsUsingNullDstDeviceId() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getDisjointPaths() method using a null dst device identifier.
+        Set<DisjointPath> paths = topologyService.getDisjointPaths(topology, srcVirtualDevice.id(), null);
+    }
+
+    /**
+     * Test getDisjointPaths() methods using a null weight.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDisjointPathsUsingNullWeight() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getDisjointPaths() method using a null weight.
+        Set<DisjointPath> paths = topologyService.getDisjointPaths(topology, srcVirtualDevice.id(),
+                                                                   dstVirtualDevice.id(), (LinkWeigher) null);
+    }
+
+    /**
+     * Test getDisjointPaths() methods using a null risk profile.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetDisjointPathsUsingNullRiskProfile() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getDisjointPaths() method using a null risk profile.
+        Set<DisjointPath> paths = topologyService.getDisjointPaths(topology, srcVirtualDevice.id(),
+                                                                   dstVirtualDevice.id(), (Map<Link, Object>) null);
+    }
+
+    /**
+     * Test getDisjointPaths() methods.
+     */
+    @Test
+    public void testGetDisjointPaths() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID2);
+
+        // test the getDisjointPaths() method.
+        Set<DisjointPath> paths = topologyService.getDisjointPaths(topology, srcVirtualDevice.id(),
+                                                                   dstVirtualDevice.id());
+        assertNotNull("The paths should not be null.", paths);
+        assertEquals("The paths size did not match.", 1, paths.size());
+
+        // test the getDisjointPaths() method using a weight.
+        LinkWeigher weight = new LinkWeigherAdapter(1.0);
+        Set<DisjointPath> paths1 = topologyService.getDisjointPaths(topology, srcVirtualDevice.id(),
+                                                                    dstVirtualDevice.id(), weight);
+        assertNotNull("The paths should not be null.", paths1);
+        assertEquals("The paths size did not match.", 1, paths1.size());
+    }
+
+    /**
+     * Test isInfrastructure() method using a null connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsInfrastructureUsingNullConnectPoint() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        // test the isInfrastructure() method using a null connect point.
+        Boolean isInfrastructure = topologyService.isInfrastructure(topology, null);
+    }
+
+    /**
+     * Test isInfrastructure() method.
+     */
+    @Test
+    public void testIsInfrastructure() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice dstVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID4);
+        ConnectPoint cp1 = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+        ConnectPoint cp2 = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+
+        // test the isInfrastructure() method.
+        Boolean isInfrastructure = topologyService.isInfrastructure(topology, cp1);
+        assertTrue("The connect point should be infrastructure.", isInfrastructure);
+
+        isInfrastructure = topologyService.isInfrastructure(topology, cp2);
+        assertFalse("The connect point should not be infrastructure.", isInfrastructure);
+    }
+
+    /**
+     * Test isBroadcastPoint() method using a null connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsBroadcastUsingNullConnectPoint() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        // test the isInfrastructure() method using a null connect point.
+        Boolean isInfrastructure = topologyService.isBroadcastPoint(topology, null);
+    }
+
+    /**
+     * Test isBroadcastPoint() method.
+     */
+    @Test
+    public void testIsBroadcastPoint() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        TopologyService topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+
+        VirtualDevice srcVirtualDevice = getVirtualDevice(virtualNetwork.id(), DID1);
+        ConnectPoint cp = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+
+        // test the isBroadcastPoint() method.
+        Boolean isBroadcastPoint = topologyService.isBroadcastPoint(topology, cp);
+        assertTrue("The connect point should be a broadcast point.", isBroadcastPoint);
+    }
+
+    /**
+     * Return the virtual device matching the device identifier.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId  device identifier
+     * @return virtual device
+     */
+    private VirtualDevice getVirtualDevice(NetworkId networkId, DeviceId deviceId) {
+        Optional<VirtualDevice> foundDevice = manager.getVirtualDevices(networkId)
+                .stream()
+                .filter(device -> deviceId.equals(device.id()))
+                .findFirst();
+        if (foundDevice.isPresent()) {
+            return foundDevice.get();
+        }
+        return null;
+    }
+
+    /**
+     * Core service test class.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+        ApplicationId appId;
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            appId = new DefaultApplicationId(1, name);
+            return appId;
+        }
+
+            @Override
+        public ApplicationId getAppId(String name) {
+            return appId;
+        }
+    }
+
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java
new file mode 100644
index 0000000..8e11e6f
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl.provider;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.graph.ScalarWeight;
+import org.onlab.graph.Weight;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
+import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminServiceAdapter;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DefaultPath;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleServiceAdapter;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.topology.LinkWeigher;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyServiceAdapter;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+
+public class DefaultVirtualFlowRuleProviderTest {
+    private static final ProviderId PID = new ProviderId("of", "foo");
+
+    private static final DeviceId DID1 = DeviceId.deviceId("of:001");
+    private static final DeviceId DID2 = DeviceId.deviceId("of:002");
+    private static final PortNumber PORT_NUM1 = PortNumber.portNumber(1);
+    private static final PortNumber PORT_NUM2 = PortNumber.portNumber(2);
+
+    private static final DefaultAnnotations ANNOTATIONS =
+            DefaultAnnotations.builder().set("foo", "bar").build();
+
+    private static final Device DEV1 =
+            new DefaultDevice(PID, DID1, Device.Type.SWITCH, "", "", "", "", null);
+    private static final Device DEV2 =
+            new DefaultDevice(PID, DID2, Device.Type.SWITCH, "", "", "", "", null);
+    private static final Port PORT11 =
+            new DefaultPort(DEV1, PORT_NUM1, true, ANNOTATIONS);
+    private static final Port PORT12 =
+            new DefaultPort(DEV1, PORT_NUM2, true, ANNOTATIONS);
+    private static final Port PORT21 =
+            new DefaultPort(DEV2, PORT_NUM1, true, ANNOTATIONS);
+    private static final Port PORT22 =
+            new DefaultPort(DEV2, PORT_NUM2, true, ANNOTATIONS);
+
+    private static final ConnectPoint CP11 = new ConnectPoint(DID1, PORT_NUM1);
+    private static final ConnectPoint CP12 = new ConnectPoint(DID1, PORT_NUM2);
+    private static final ConnectPoint CP21 = new ConnectPoint(DID2, PORT_NUM1);
+    private static final ConnectPoint CP22 = new ConnectPoint(DID2, PORT_NUM2);
+    private static final Link LINK1 = DefaultLink.builder()
+            .src(CP12).dst(CP21).providerId(PID).type(Link.Type.DIRECT).build();
+
+    private static final NetworkId VNET_ID = NetworkId.networkId(1);
+    private static final DeviceId VDID = DeviceId.deviceId("of:100");
+
+    private static final VirtualNetwork VNET = new DefaultVirtualNetwork(
+            VNET_ID, TenantId.tenantId("t1"));
+    private static final VirtualDevice VDEV =
+            new DefaultVirtualDevice(VNET_ID, VDID);
+    private static final VirtualPort VPORT1 =
+            new DefaultVirtualPort(VNET_ID, VDEV, PORT_NUM1, CP11);
+    private static final VirtualPort VPORT2 =
+            new DefaultVirtualPort(VNET_ID, VDEV, PORT_NUM2, CP22);
+
+    private static final int TIMEOUT = 10;
+
+    protected DefaultVirtualFlowRuleProvider virtualProvider;
+
+    private ApplicationId vAppId;
+
+    @Before
+    public void setUp() {
+        virtualProvider = new DefaultVirtualFlowRuleProvider();
+
+        virtualProvider.deviceService = new TestDeviceService();
+        virtualProvider.coreService = new TestCoreService();
+        virtualProvider.vnService =
+                new TestVirtualNetworkAdminService();
+        virtualProvider.topologyService = new TestTopologyService();
+        virtualProvider.flowRuleService = new TestFlowRuleService();
+        virtualProvider.providerRegistryService = new VirtualProviderManager();
+
+        virtualProvider.activate();
+        vAppId = new TestApplicationId(0, "Virtual App");
+    }
+
+    @After
+    public void tearDown() {
+        virtualProvider.deactivate();
+        virtualProvider.deviceService = null;
+        virtualProvider.coreService = null;
+    }
+
+    @Test
+    public void devirtualizeFlowRuleWithInPort() {
+        TrafficSelector ts = DefaultTrafficSelector.builder()
+                .matchInPort(PORT_NUM1).build();
+        TrafficTreatment tr = DefaultTrafficTreatment.builder()
+                .setOutput(PORT_NUM2).build();
+
+        FlowRule r1 = DefaultFlowRule.builder()
+                .forDevice(VDID)
+                .withSelector(ts)
+                .withTreatment(tr)
+                .withPriority(10)
+                .fromApp(vAppId)
+                .makeTemporary(TIMEOUT)
+                .build();
+
+        virtualProvider.applyFlowRule(VNET_ID, r1);
+
+        assertEquals("2 rules should exist", 2,
+                     virtualProvider.flowRuleService.getFlowRuleCount());
+
+        Set<FlowEntry> phyRules = new HashSet<>();
+        for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID1)) {
+            phyRules.add(i);
+        }
+        for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID2)) {
+            phyRules.add(i);
+        }
+
+        FlowRule in = null;
+        FlowRule out = null;
+
+        for (FlowRule rule : phyRules) {
+
+            L2ModificationInstruction i = (L2ModificationInstruction)
+                    rule.treatment().allInstructions().get(0);
+
+            if (i.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
+                in = rule;
+            } else {
+                out = rule;
+            }
+
+        }
+
+        assertEquals(DID1, in.deviceId());
+        assertEquals(DID2, out.deviceId());
+    }
+
+    @Test
+    public void devirtualizeFlowRuleWithoutInPort() {
+        TrafficSelector ts = DefaultTrafficSelector.builder().build();
+        TrafficTreatment tr = DefaultTrafficTreatment.builder()
+                .setOutput(PORT_NUM2).build();
+
+        FlowRule r1 = DefaultFlowRule.builder()
+                .forDevice(VDID)
+                .withSelector(ts)
+                .withTreatment(tr)
+                .withPriority(10)
+                .fromApp(vAppId)
+                .makeTemporary(TIMEOUT)
+                .build();
+
+        virtualProvider.applyFlowRule(VNET_ID, r1);
+
+        assertEquals("3 rules should exist", 3,
+                     virtualProvider.flowRuleService.getFlowRuleCount());
+
+        FlowRule inFromDID1 = null;
+        FlowRule inFromDID2 = null;
+        FlowRule out = null;
+
+        Set<FlowEntry> phyRules = new HashSet<>();
+        for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID1)) {
+            phyRules.add(i);
+        }
+        for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID2)) {
+            phyRules.add(i);
+        }
+
+        for (FlowRule rule : phyRules) {
+            for (Instruction inst : rule.treatment().allInstructions()) {
+                if (inst.type() == Instruction.Type.L2MODIFICATION) {
+                    L2ModificationInstruction i = (L2ModificationInstruction) inst;
+                    if (i.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
+                        inFromDID1 = rule;
+                        break;
+                    } else {
+                        out = rule;
+                        break;
+                    }
+                } else {
+                    inFromDID2 = rule;
+                    break;
+                }
+            }
+        }
+
+        assertEquals(DID1, inFromDID1.deviceId());
+        assertEquals(DID2, inFromDID2.deviceId());
+        assertEquals(DID2, out.deviceId());
+    }
+
+    @Test
+    public void removeVirtualizeFlowRule() {
+        TrafficSelector ts = DefaultTrafficSelector.builder().build();
+        TrafficTreatment tr = DefaultTrafficTreatment.builder()
+                .setOutput(PORT_NUM2).build();
+
+        FlowRule r1 = DefaultFlowRule.builder()
+                .forDevice(VDID)
+                .withSelector(ts)
+                .withTreatment(tr)
+                .withPriority(10)
+                .fromApp(vAppId)
+                .makeTemporary(TIMEOUT)
+                .build();
+
+        virtualProvider.removeFlowRule(VNET_ID, r1);
+
+        assertEquals("0 rules should exist", 0,
+                     virtualProvider.flowRuleService.getFlowRuleCount());
+    }
+
+
+    private static class TestDeviceService extends DeviceServiceAdapter {
+        @Override
+        public int getDeviceCount() {
+            return 2;
+        }
+
+        @Override
+        public Iterable<Device> getDevices() {
+            return ImmutableList.of(DEV1, DEV2);
+        }
+
+        @Override
+        public Iterable<Device> getAvailableDevices() {
+            return getDevices();
+        }
+
+        @Override
+        public Device getDevice(DeviceId deviceId) {
+            return deviceId.equals(DID2) ? DEV2 : DEV1;
+        }
+    }
+
+    private static class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return new TestApplicationId(1, name);
+        }
+    }
+
+    private static class TestApplicationId extends DefaultApplicationId {
+        public TestApplicationId(int id, String name) {
+            super(id, name);
+        }
+    }
+
+    private class TestVirtualNetworkAdminService
+            extends VirtualNetworkAdminServiceAdapter {
+
+        @Override
+        public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
+            return ImmutableSet.of(VDEV);
+        }
+
+        @Override
+        public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
+            return new HashSet<>();
+        }
+
+        @Override
+        public Set<VirtualPort> getVirtualPorts(NetworkId networkId,
+                                                DeviceId deviceId) {
+            return ImmutableSet.of(VPORT1, VPORT2);
+        }
+
+        @Override
+        public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) {
+            return vAppId;
+        }
+    }
+
+    private static class TestTopologyService extends TopologyServiceAdapter {
+
+        Weight oneHundred = ScalarWeight.toWeight(100);
+        @Override
+        public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst) {
+            DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
+                                               oneHundred, ANNOTATIONS);
+            return ImmutableSet.of(path);
+        }
+
+        @Override
+        public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst,
+                                  LinkWeigher weigher) {
+            DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
+                                               oneHundred, ANNOTATIONS);
+            return ImmutableSet.of(path);
+        }
+
+    }
+
+    private static class TestFlowRuleService extends FlowRuleServiceAdapter {
+        static Set<FlowRule> ruleCollection = new HashSet<>();
+
+        @Override
+        public int getFlowRuleCount() {
+            return ruleCollection.size();
+        }
+
+        @Override
+        public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
+            return ruleCollection.stream()
+                    .filter(r -> r.deviceId().equals(deviceId))
+                    .map(DefaultFlowEntry::new)
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public void applyFlowRules(FlowRule... flowRules) {
+            ruleCollection.addAll(Arrays.asList(flowRules));
+        }
+
+        @Override
+        public void removeFlowRules(FlowRule... flowRules) {
+            Set<FlowRule> candidates = new HashSet<>();
+            for (FlowRule rule : flowRules) {
+                ruleCollection.stream()
+                        .filter(r -> r.exactMatch(rule))
+                        .forEach(candidates::add);
+            }
+            ruleCollection.removeAll(candidates);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketProviderTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketProviderTest.java
new file mode 100644
index 0000000..a17a0db
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketProviderTest.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl.provider;
+
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
+import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminServiceAdapter;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualPacketProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualPacketProviderService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+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.onosproject.net.provider.ProviderId;
+
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+public class DefaultVirtualPacketProviderTest {
+    private static final String SRC_MAC_ADDR = "00:00:00:00:00:00";
+    private static final String DST_MAC_ADDR = "00:00:00:00:00:01";
+    private static final ProviderId PID = new ProviderId("of", "foo");
+
+    private static final DeviceId DID1 = DeviceId.deviceId("of:001");
+    private static final DeviceId DID2 = DeviceId.deviceId("of:002");
+    private static final PortNumber PORT_NUM1 = PortNumber.portNumber(1);
+    private static final PortNumber PORT_NUM2 = PortNumber.portNumber(2);
+    private static final PortNumber PORT_NUM3 = PortNumber.portNumber(3);
+    private static final PortNumber PORT_NUM4 = PortNumber.portNumber(4);
+
+    private static final DefaultAnnotations ANNOTATIONS =
+            DefaultAnnotations.builder().set("foo", "bar").build();
+
+    private static final Device DEV1 =
+            new DefaultDevice(PID, DID1, Device.Type.SWITCH, "", "", "", "", null);
+    private static final Device DEV2 =
+            new DefaultDevice(PID, DID2, Device.Type.SWITCH, "", "", "", "", null);
+    private static final Port PORT11 =
+            new DefaultPort(DEV1, PORT_NUM1, true, ANNOTATIONS);
+    private static final Port PORT12 =
+            new DefaultPort(DEV1, PORT_NUM2, true, ANNOTATIONS);
+    private static final Port PORT21 =
+            new DefaultPort(DEV2, PORT_NUM3, true, ANNOTATIONS);
+    private static final Port PORT22 =
+            new DefaultPort(DEV2, PORT_NUM4, true, ANNOTATIONS);
+
+    private static final ConnectPoint CP11 = new ConnectPoint(DID1, PORT_NUM1);
+    private static final ConnectPoint CP12 = new ConnectPoint(DID1, PORT_NUM2);
+    private static final ConnectPoint CP21 = new ConnectPoint(DID2, PORT_NUM3);
+    private static final ConnectPoint CP22 = new ConnectPoint(DID2, PORT_NUM4);
+    private static final Link LINK1 = DefaultLink.builder()
+            .src(CP12).dst(CP21).providerId(PID).type(Link.Type.DIRECT).build();
+
+    private static final TenantId TENANT_ID = TenantId.tenantId("1");
+    private static final NetworkId VNET_ID = NetworkId.networkId(1);
+    private static final DeviceId VDID = DeviceId.deviceId("of:100");
+
+    private static final PortNumber VPORT_NUM1 = PortNumber.portNumber(10);
+    private static final PortNumber VPORT_NUM2 = PortNumber.portNumber(11);
+
+    private static final VirtualNetwork VNET = new DefaultVirtualNetwork(
+            VNET_ID, TenantId.tenantId("t1"));
+    private static final VirtualDevice VDEV =
+            new DefaultVirtualDevice(VNET_ID, VDID);
+    private static final VirtualPort VPORT1 =
+            new DefaultVirtualPort(VNET_ID, VDEV, VPORT_NUM1, CP11);
+    private static final VirtualPort VPORT2 =
+            new DefaultVirtualPort(VNET_ID, VDEV, VPORT_NUM2, CP22);
+    private static final ConnectPoint VCP11 = new ConnectPoint(VDID, VPORT_NUM1);
+    private static final ConnectPoint VCP12 = new ConnectPoint(VDID, VPORT_NUM2);
+
+    protected DefaultVirtualPacketProvider virtualProvider;
+    protected TestPacketService testPacketService;
+    protected TestVirtualPacketProviderService providerService;
+
+    private VirtualProviderManager providerManager;
+
+    private ApplicationId vAppId;
+
+    @Before
+    public void setUp() {
+        virtualProvider = new DefaultVirtualPacketProvider();
+
+        virtualProvider.coreService = new CoreServiceAdapter();
+        virtualProvider.vnaService =
+                new TestVirtualNetworkAdminService();
+
+        providerService = new TestVirtualPacketProviderService();
+
+        testPacketService = new TestPacketService();
+        virtualProvider.packetService = testPacketService;
+
+        providerManager = new VirtualProviderManager();
+        virtualProvider.providerRegistryService = providerManager;
+        providerManager.registerProviderService(VNET_ID, providerService);
+
+        virtualProvider.activate();
+        vAppId = new TestApplicationId(0, "Virtual App");
+
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+
+        virtualProvider.startPacketHandling();
+    }
+
+    @After
+    public void tearDown() {
+        virtualProvider.deactivate();
+        virtualProvider.coreService = null;
+        virtualProvider.vnaService = null;
+    }
+
+
+    /** Test the virtual outbound packet is delivered to a proper (physical)
+     *  device.
+     */
+    @Test
+    public void devirtualizePacket() {
+        TrafficTreatment tr = DefaultTrafficTreatment.builder()
+                .setOutput(VPORT_NUM1).build();
+        ByteBuffer data = ByteBuffer.wrap("abc".getBytes());
+
+        OutboundPacket vOutPacket = new DefaultOutboundPacket(VDID, tr, data);
+
+        virtualProvider.emit(VNET_ID, vOutPacket);
+
+        assertEquals("The count should be 1", 1,
+                     testPacketService.getRequestedPacketCount());
+
+        OutboundPacket pOutPacket = testPacketService.getRequestedPacket(0);
+
+        assertEquals("The packet should be requested on DEV1", DID1,
+                     pOutPacket.sendThrough());
+
+        PortNumber outPort = pOutPacket.treatment()
+                .allInstructions()
+                .stream()
+                .filter(i -> i.type() == Instruction.Type.OUTPUT)
+                .map(i -> (Instructions.OutputInstruction) i)
+                .map(i -> i.port())
+                .findFirst().get();
+        assertEquals("The packet should be out at PORT1 of DEV1", PORT_NUM1,
+                     outPort);
+    }
+
+    /** Test the physical packet context is delivered to a proper (physical)
+     *  virtual network and device.
+     */
+    @Test
+    public void virtualizePacket() {
+        Ethernet eth = new Ethernet();
+        eth.setSourceMACAddress(SRC_MAC_ADDR);
+        eth.setDestinationMACAddress(DST_MAC_ADDR);
+        eth.setVlanID((short) 1);
+        eth.setPayload(null);
+
+        InboundPacket pInPacket =
+                new DefaultInboundPacket(CP22, eth,
+                                         ByteBuffer.wrap(eth.serialize()));
+
+        PacketContext pContext =
+                new TestPacketContext(System.nanoTime(), pInPacket, null, false);
+
+        testPacketService.sendTestPacketContext(pContext);
+
+        PacketContext vContext = providerService.getRequestedPacketContext(0);
+        InboundPacket vInPacket = vContext.inPacket();
+
+        assertEquals("the packet should be received from VCP12",
+                     VCP12, vInPacket.receivedFrom());
+
+        assertEquals("VLAN tag should be excludede", VlanId.UNTAGGED,
+                     vInPacket.parsed().getVlanID());
+    }
+
+    private class TestPacketContext extends DefaultPacketContext {
+
+        /**
+         * Creates a new packet context.
+         *
+         * @param time   creation time
+         * @param inPkt  inbound packet
+         * @param outPkt outbound packet
+         * @param block  whether the context is blocked or not
+         */
+        protected TestPacketContext(long time, InboundPacket inPkt,
+                                    OutboundPacket outPkt, boolean block) {
+            super(time, inPkt, outPkt, block);
+        }
+
+        @Override
+        public void send() {
+
+        }
+    }
+
+    private static class TestApplicationId extends DefaultApplicationId {
+        public TestApplicationId(int id, String name) {
+            super(id, name);
+        }
+    }
+
+    private static class TestVirtualNetworkAdminService
+            extends VirtualNetworkAdminServiceAdapter {
+
+        @Override
+        public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
+            return ImmutableSet.of(VNET);
+        }
+
+        @Override
+        public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
+            return ImmutableSet.of(VDEV);
+        }
+
+        @Override
+        public Set<VirtualPort> getVirtualPorts(NetworkId networkId,
+                                                DeviceId deviceId) {
+            return ImmutableSet.of(VPORT1, VPORT2);
+        }
+
+        @Override
+        public Set<TenantId> getTenantIds() {
+            return ImmutableSet.of(TENANT_ID);
+        }
+
+    }
+
+    private static class TestVirtualPacketProviderService
+            extends AbstractVirtualProviderService<VirtualPacketProvider>
+            implements VirtualPacketProviderService {
+
+        static List<PacketContext> requestedContext = new LinkedList();
+        static List<NetworkId> requestedNetworkId = new LinkedList();
+
+        @Override
+        public VirtualPacketProvider provider() {
+            return null;
+        }
+
+        PacketContext getRequestedPacketContext(int index) {
+            return requestedContext.get(index);
+        }
+
+        @Override
+        public void processPacket(PacketContext context) {
+            requestedContext.add(context);
+        }
+    }
+
+    private static class TestPacketService extends PacketServiceAdapter {
+        static List<OutboundPacket> requestedPacket = new LinkedList();
+        static PacketProcessor processor = null;
+
+        @Override
+        public void addProcessor(PacketProcessor processor, int priority) {
+            this.processor = processor;
+        }
+
+        @Override
+        public void emit(OutboundPacket packet) {
+            requestedPacket.add(packet);
+        }
+
+        OutboundPacket getRequestedPacket(int index) {
+            return requestedPacket.get(index);
+        }
+
+        int getRequestedPacketCount() {
+            return requestedPacket.size();
+        }
+
+        void sendTestPacketContext(PacketContext context) {
+            processor.process(context);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualNetworkTopologyProviderTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualNetworkTopologyProviderTest.java
new file mode 100644
index 0000000..ee03783
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualNetworkTopologyProviderTest.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl.provider;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.event.Event;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderRegistry;
+import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderService;
+import org.onosproject.incubator.net.virtual.impl.VirtualNetworkManager;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+import org.onosproject.net.intent.FakeIntentManager;
+import org.onosproject.net.intent.TestableIntentService;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.provider.AbstractProviderService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.topology.TopologyEvent;
+import org.onosproject.net.topology.TopologyService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.*;
+
+/**
+ * Junit tests for VirtualNetworkTopologyProvider.
+ */
+public class VirtualNetworkTopologyProviderTest extends TestDeviceParams {
+
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetwork virtualNetwork;
+    private VirtualDevice virtualDevice1;
+    private VirtualDevice virtualDevice2;
+    private VirtualDevice virtualDevice3;
+    private VirtualDevice virtualDevice4;
+    private VirtualDevice virtualDevice5;
+    private ConnectPoint cp1;
+    private ConnectPoint cp2;
+    private ConnectPoint cp3;
+    private ConnectPoint cp4;
+    private ConnectPoint cp5;
+    private ConnectPoint cp6;
+    private ConnectPoint cp7;
+    private ConnectPoint cp8;
+    private ConnectPoint cp9;
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService;
+    private DefaultVirtualNetworkProvider topologyProvider;
+    private TopologyService topologyService;
+    private TestableIntentService intentService = new FakeIntentManager();
+    private TestServiceDirectory testDirectory;
+    private final VirtualNetworkRegistryAdapter virtualNetworkRegistry = new VirtualNetworkRegistryAdapter();
+
+    private static final int MAX_WAIT_TIME = 5;
+    private static final int MAX_PERMITS = 1;
+    private static Semaphore changed;
+
+    private Set<Set<ConnectPoint>> clusters;
+
+    @Before
+    public void setUp() throws Exception {
+
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        coreService = new VirtualNetworkTopologyProviderTest.TestCoreService();
+
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService",
+                           new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        TestUtils.setField(manager, "coreService", coreService);
+        TestUtils.setField(manager, "store", virtualNetworkManagerStore);
+        TestUtils.setField(manager, "intentService", intentService);
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        topologyProvider = new DefaultVirtualNetworkProvider();
+        topologyProvider.topologyService = topologyService;
+        topologyProvider.providerRegistry = virtualNetworkRegistry;
+        topologyProvider.activate();
+
+        setupVirtualNetworkTopology();
+        changed = new Semaphore(0, true);
+    }
+
+    @After
+    public void tearDown() {
+        topologyProvider.deactivate();
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+    }
+
+    /**
+     * Method to create the virtual network for further testing.
+     **/
+    private void setupVirtualNetworkTopology() {
+        virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        virtualDevice3 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID3);
+        virtualDevice4 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID4);
+        virtualDevice5 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID5);
+
+        cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
+                                  PortNumber.portNumber(1), cp1);
+
+        cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
+                                  PortNumber.portNumber(2), cp2);
+
+        cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
+                                  PortNumber.portNumber(3), cp3);
+
+        cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
+                                  PortNumber.portNumber(4), cp4);
+
+        cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
+                                  PortNumber.portNumber(5), cp5);
+
+        cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
+                                  PortNumber.portNumber(6), cp6);
+
+        cp7 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(7));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
+                                  PortNumber.portNumber(7), cp7);
+
+        cp8 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(8));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
+                                  PortNumber.portNumber(8), cp8);
+
+        cp9 = new ConnectPoint(virtualDevice5.id(), PortNumber.portNumber(9));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice5.id(),
+                                  PortNumber.portNumber(9), cp9);
+
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
+        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
+        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp8, cp9);
+        virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp9, cp8);
+        virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
+
+        clusters = null;
+    }
+
+    /**
+     * Test isTraversable() method using a null source connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsTraversableNullSrc() {
+        // test the isTraversable() method with a null source connect point.
+        topologyProvider.isTraversable(null, cp3);
+    }
+
+    /**
+     * Test isTraversable() method using a null destination connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsTraversableNullDst() {
+        // test the isTraversable() method with a null destination connect point.
+        topologyProvider.isTraversable(cp1, null);
+    }
+
+    /**
+     * Test isTraversable() method.
+     */
+    @Test
+    public void testIsTraversable() {
+        // test the isTraversable() method.
+        assertTrue("These two connect points should be traversable.",
+                   topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()),
+                                                  new ConnectPoint(cp3.elementId(), cp3.port())));
+        assertTrue("These two connect points should be traversable.",
+                   topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()),
+                                                  new ConnectPoint(cp5.elementId(), cp5.port())));
+        assertFalse("These two connect points should not be traversable.",
+                    topologyProvider.isTraversable(
+                            new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1)),
+                            new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(6))));
+    }
+
+    /**
+     * Test the topologyChanged() method.
+     */
+    @Test
+    public void testTopologyChanged() {
+        // Initial setup is two clusters of devices/links.
+        assertEquals("The cluster count did not match.", 2,
+                     topologyService.currentTopology().clusterCount());
+
+        // Adding this link will join the two clusters together.
+        List<Event> reasons = new ArrayList<>();
+        VirtualLink link = manager.createVirtualLink(virtualNetwork.id(), cp6, cp7);
+        virtualNetworkManagerStore.updateLink(link, link.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp7, cp6);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+
+        reasons.add(new LinkEvent(LinkEvent.Type.LINK_ADDED, link));
+        reasons.add(new LinkEvent(LinkEvent.Type.LINK_ADDED, link2));
+        TopologyEvent event = new TopologyEvent(
+                TopologyEvent.Type.TOPOLOGY_CHANGED,
+                topologyService.currentTopology(),
+                reasons);
+
+        topologyProvider.topologyListener.event(event);
+
+        // Wait for the topology changed event, and that the topologyChanged method was called.
+        try {
+            if (!changed.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for topology changed event.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception." + e.getMessage());
+        }
+
+        // Validate that the topology changed method received a single cluster of connect points.
+        // This means that the two previous clusters have now joined into a single cluster.
+        assertEquals("The cluster count did not match.", 1, this.clusters.size());
+        assertEquals("The cluster count did not match.", 1,
+                     topologyService.currentTopology().clusterCount());
+
+        // Now remove the virtual link to split it back into two clusters.
+        manager.removeVirtualLink(virtualNetwork.id(), link.src(), link.dst());
+        manager.removeVirtualLink(virtualNetwork.id(), link2.src(), link2.dst());
+        assertEquals("The cluster count did not match.", 2,
+                     topologyService.currentTopology().clusterCount());
+
+        reasons = new ArrayList<>();
+        reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link));
+        reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2));
+        event = new TopologyEvent(
+                TopologyEvent.Type.TOPOLOGY_CHANGED,
+                topologyService.currentTopology(),
+                reasons);
+
+        topologyProvider.topologyListener.event(event);
+
+        // Wait for the topology changed event, and that the topologyChanged method was called.
+        try {
+            if (!changed.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for topology changed event.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception." + e.getMessage());
+        }
+
+        // Validate that the topology changed method received two clusters of connect points.
+        // This means that the single previous clusters has now split into two clusters.
+        assertEquals("The cluster count did not match.", 2, this.clusters.size());
+    }
+
+    /**
+     * Virtual network registry implementation for this test class.
+     */
+    private class VirtualNetworkRegistryAdapter implements VirtualNetworkProviderRegistry {
+        private VirtualNetworkProvider provider;
+
+        @Override
+        public VirtualNetworkProviderService register(VirtualNetworkProvider theProvider) {
+            this.provider = theProvider;
+            return new TestVirtualNetworkProviderService(theProvider);
+        }
+
+        @Override
+        public void unregister(VirtualNetworkProvider theProvider) {
+            this.provider = null;
+        }
+
+        @Override
+        public Set<ProviderId> getProviders() {
+            return null;
+        }
+    }
+
+
+    /**
+     * Virtual network provider service implementation for this test class.
+     */
+    private class TestVirtualNetworkProviderService
+            extends AbstractProviderService<VirtualNetworkProvider>
+            implements VirtualNetworkProviderService {
+
+        /**
+         * Constructor.
+         *
+         * @param provider virtual network test provider
+         */
+        protected TestVirtualNetworkProviderService(VirtualNetworkProvider provider) {
+            super(provider);
+        }
+
+        @Override
+        public void topologyChanged(Set<Set<ConnectPoint>> theClusters) {
+            clusters = theClusters;
+            changed.release();
+        }
+
+        @Override
+        public void tunnelUp(NetworkId networkId, ConnectPoint src,
+                             ConnectPoint dst, TunnelId tunnelId) {
+        }
+
+        @Override
+        public void tunnelDown(NetworkId networkId, ConnectPoint src,
+                               ConnectPoint dst, TunnelId tunnelId) {
+        }
+    }
+
+    /**
+     * Core service test class.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java
new file mode 100644
index 0000000..90e1664
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.onosproject.incubator.net.virtual.impl.provider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
+import org.onosproject.net.provider.ProviderId;
+
+import static org.junit.Assert.assertEquals;
+
+public class VirtualProviderManagerTest {
+
+    private static final String TEST_SCHEME1 = "test1";
+    private static final String TEST_SCHEME2 = "test2";
+    private static final String TEST_ID1 = "org.onosproject.virtual.testprovider1";
+    private static final String TEST_ID2 = "org.onosproject.virtual.testprovider1";
+    private static final NetworkId NETWORK_ID1 = NetworkId.networkId(1);
+    private static final NetworkId NETWORK_ID2 = NetworkId.networkId(2);
+
+    VirtualProviderManager virtualProviderManager;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualProviderManager = new VirtualProviderManager();
+    }
+
+    /**
+     * Tests registerProvider() and unregisterProvider().
+     */
+    @Test
+    public void registerProviderTest() {
+        TestProvider1 provider1 = new TestProvider1();
+        virtualProviderManager.registerProvider(provider1);
+
+        assertEquals("The number of registered provider did not match.", 1,
+                     virtualProviderManager.getProviders().size());
+
+        assertEquals("The registered provider did not match", provider1,
+                     virtualProviderManager.getProvider(TEST_SCHEME1));
+
+        virtualProviderManager.unregisterProvider(provider1);
+
+        TestProvider2 provider2 = new TestProvider2();
+        virtualProviderManager.registerProvider(provider2);
+
+        assertEquals("The number of registered provider did not match.", 1,
+                     virtualProviderManager.getProviders().size());
+
+        virtualProviderManager.unregisterProvider(provider2);
+
+        assertEquals("The number of registered provider did not match.", 0,
+                     virtualProviderManager.getProviders().size());
+    }
+
+    /**
+     * Tests registerProviderService() and getProviderService().
+     */
+    @Test
+    public void registerProviderServiceTest() {
+        TestProvider1 provider1 = new TestProvider1();
+        virtualProviderManager.registerProvider(provider1);
+
+        TestProviderService1 providerService1 = new TestProviderService1();
+        virtualProviderManager.registerProviderService(NETWORK_ID1, providerService1);
+
+        assertEquals(providerService1,
+                     virtualProviderManager.getProviderService(NETWORK_ID1, TestProvider1.class));
+    }
+
+    private class TestProvider1 extends AbstractVirtualProvider {
+        protected TestProvider1() {
+            super(new ProviderId(TEST_SCHEME1, TEST_ID1));
+        }
+    }
+
+    private class TestProvider2 extends AbstractVirtualProvider {
+        protected TestProvider2() {
+            super(new ProviderId(TEST_SCHEME2, TEST_ID2));
+        }
+    }
+
+    private class TestProviderService1 extends AbstractVirtualProviderService<TestProvider1> {
+    }
+
+    private class TestProviderService2 extends AbstractVirtualProviderService<TestProvider2> {
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/TenantWebResourceTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/TenantWebResourceTest.java
new file mode 100644
index 0000000..def32c5
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/TenantWebResourceTest.java
@@ -0,0 +1,334 @@
+/*
+ * 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.incubator.net.virtual.rest;
+
+import com.eclipsesource.json.Json;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableSet;
+import org.glassfish.jersey.client.ClientProperties;
+import org.hamcrest.Description;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.rest.resources.ResourceTest;
+
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.NotFoundException;
+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 java.net.HttpURLConnection;
+import java.util.HashSet;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * Unit tests for tenant REST APIs.
+ */
+@Ignore
+public class TenantWebResourceTest extends ResourceTest {
+
+    private final VirtualNetworkAdminService mockVnetAdminService = createMock(VirtualNetworkAdminService.class);
+
+    final HashSet<TenantId> tenantIdSet = new HashSet<>();
+
+    private static final String ID = "id";
+
+    private final TenantId tenantId1 = TenantId.tenantId("TenantId1");
+    private final TenantId tenantId2 = TenantId.tenantId("TenantId2");
+    private final TenantId tenantId3 = TenantId.tenantId("TenantId3");
+    private final TenantId tenantId4 = TenantId.tenantId("TenantId4");
+
+    /**
+     * Sets up the global values for all the tests.
+     */
+    @Before
+    public void setUpTest() {
+        // Register the services needed for the test
+        CodecManager codecService = new CodecManager();
+        codecService.activate();
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(VirtualNetworkAdminService.class, mockVnetAdminService)
+                        .add(CodecService.class, codecService);
+
+        setServiceDirectory(testDirectory);
+    }
+
+    /**
+     * Hamcrest matcher to check that a tenant id representation in JSON matches
+     * the actual tenant id.
+     */
+    public static class TenantIdJsonMatcher extends TypeSafeMatcher<JsonObject> {
+        private final TenantId tenantId;
+        private String reason = "";
+
+        public TenantIdJsonMatcher(TenantId tenantIdValue) {
+            tenantId = tenantIdValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonHost) {
+            // Check the tenant id
+            final String jsonId = jsonHost.get(ID).asString();
+            if (!jsonId.equals(tenantId.id())) {
+                reason = ID + " " + tenantId.id();
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a tenant id array matcher.
+     *
+     * @param tenantId tenant id object we are looking for
+     * @return matcher
+     */
+    private static TenantIdJsonMatcher matchesTenantId(TenantId tenantId) {
+        return new TenantIdJsonMatcher(tenantId);
+    }
+
+    /**
+     * Hamcrest matcher to check that a tenant id is represented properly in a JSON
+     * array of tenant ids.
+     */
+    public static class TenantIdJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+        private final TenantId tenantId;
+        private String reason = "";
+
+        public TenantIdJsonArrayMatcher(TenantId tenantIdValue) {
+            tenantId = tenantIdValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            boolean tenantIdFound = false;
+            final int expectedAttributes = 1;
+            for (int tenantIdIndex = 0; tenantIdIndex < json.size();
+                 tenantIdIndex++) {
+
+                final JsonObject jsonHost = json.get(tenantIdIndex).asObject();
+
+                // Only 1 attribute - ID.
+                if (jsonHost.names().size() < expectedAttributes) {
+                    reason = "Found a tenant id with the wrong number of attributes";
+                    return false;
+                }
+
+                final String jsonDeviceKeyId = jsonHost.get(ID).asString();
+                if (jsonDeviceKeyId.equals(tenantId.id())) {
+                    tenantIdFound = true;
+
+                    //  We found the correct tenant id, check the tenant id attribute values
+                    assertThat(jsonHost, matchesTenantId(tenantId));
+                }
+            }
+            if (!tenantIdFound) {
+                reason = "Tenant id " + tenantId.id() + " was not found";
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a tenant id array matcher.
+     *
+     * @param tenantId tenant id object we are looking for
+     * @return matcher
+     */
+    private static TenantIdJsonArrayMatcher hasTenantId(TenantId tenantId) {
+        return new TenantIdJsonArrayMatcher(tenantId);
+    }
+
+    /**
+     * Tests the result of the REST API GET when there are no tenant ids.
+     */
+    @Test
+    public void testGetTenantsEmptyArray() {
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        String response = wt.path("tenants").request().get(String.class);
+        assertThat(response, is("{\"tenants\":[]}"));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when tenant ids are defined.
+     */
+    @Test
+    public void testGetTenantIdsArray() {
+        tenantIdSet.add(tenantId1);
+        tenantIdSet.add(tenantId2);
+        tenantIdSet.add(tenantId3);
+        tenantIdSet.add(tenantId4);
+        expect(mockVnetAdminService.getTenantIds()).andReturn(tenantIdSet).anyTimes();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        String response = wt.path("tenants").request().get(String.class);
+        assertThat(response, containsString("{\"tenants\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("tenants"));
+
+        final JsonArray tenantIds = result.get("tenants").asArray();
+        assertThat(tenantIds, notNullValue());
+        assertEquals("Device keys array is not the correct size.",
+                     tenantIdSet.size(), tenantIds.size());
+
+        tenantIdSet.forEach(tenantId -> assertThat(tenantIds, hasTenantId(tenantId)));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of new tenant id using POST via JSON stream.
+     */
+    @Test
+    public void testPost() {
+        mockVnetAdminService.registerTenantId(anyObject());
+        tenantIdSet.add(tenantId2);
+        expect(mockVnetAdminService.getTenantIds()).andReturn(tenantIdSet).anyTimes();
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = TenantWebResourceTest.class
+                .getResourceAsStream("post-tenant.json");
+
+        Response response = wt.path("tenants").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/tenants/" + tenantId2));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null tenant id using POST via JSON stream.
+     */
+    @Test
+    public void testPostNullTenantId() {
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String response = wt.path("tenants")
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null tenant id did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a tenant id with DELETE request.
+     */
+    @Test
+    public void testDelete() {
+        expect(mockVnetAdminService.getTenantIds())
+                .andReturn(ImmutableSet.of(tenantId2)).anyTimes();
+        mockVnetAdminService.unregisterTenantId(anyObject());
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        Response response = wt.path("tenants/" + tenantId2)
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests that a DELETE of a non-existent tenant id throws an exception.
+     */
+    @Test
+    public void testDeleteNonExistentDeviceKey() {
+        expect(mockVnetAdminService.getTenantIds())
+                .andReturn(ImmutableSet.of())
+                .anyTimes();
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+
+        try {
+            wt.path("tenants/" + "NON_EXISTENT_TENANT_ID")
+                    .request()
+                    .delete(String.class);
+            fail("Delete of a non-existent tenant did not throw an exception");
+        } catch (NotFoundException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebResourceTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebResourceTest.java
new file mode 100644
index 0000000..3b1bd51
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/rest/VirtualNetworkWebResourceTest.java
@@ -0,0 +1,1270 @@
+/*
+ * 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.incubator.net.virtual.rest;
+
+import com.eclipsesource.json.Json;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.glassfish.jersey.client.ClientProperties;
+import org.hamcrest.Description;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
+import org.onosproject.incubator.net.virtual.DefaultVirtualHost;
+import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
+import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualHost;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.PortNumber;
+import org.onosproject.rest.resources.HostResourceTest;
+import org.onosproject.rest.resources.LinksResourceTest;
+import org.onosproject.rest.resources.ResourceTest;
+
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.NotFoundException;
+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 java.net.HttpURLConnection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.onosproject.net.PortNumber.portNumber;
+
+/**
+ * Unit tests for virtual network REST APIs.
+ */
+@Ignore
+public class VirtualNetworkWebResourceTest extends ResourceTest {
+
+    private final VirtualNetworkAdminService mockVnetAdminService = createMock(VirtualNetworkAdminService.class);
+    private final VirtualNetworkService mockVnetService = createMock(VirtualNetworkService.class);
+    private CodecManager codecService;
+
+    private final HashSet<VirtualDevice> vdevSet = new HashSet<>();
+    private final HashSet<VirtualPort> vportSet = new HashSet<>();
+
+    private static final String ID = "networkId";
+    private static final String TENANT_ID = "tenantId";
+    private static final String DEVICE_ID = "deviceId";
+    private static final String PORT_NUM = "portNum";
+    private static final String PHYS_DEVICE_ID = "physDeviceId";
+    private static final String PHYS_PORT_NUM = "physPortNum";
+
+    private final TenantId tenantId2 = TenantId.tenantId("TenantId2");
+    private final TenantId tenantId3 = TenantId.tenantId("TenantId3");
+    private final TenantId tenantId4 = TenantId.tenantId("TenantId4");
+
+    private final NetworkId networkId1 = NetworkId.networkId(1);
+    private final NetworkId networkId2 = NetworkId.networkId(2);
+    private final NetworkId networkId3 = NetworkId.networkId(3);
+    private final NetworkId networkId4 = NetworkId.networkId(4);
+
+    private final VirtualNetwork vnet1 = new DefaultVirtualNetwork(networkId1, tenantId3);
+    private final VirtualNetwork vnet2 = new DefaultVirtualNetwork(networkId2, tenantId3);
+    private final VirtualNetwork vnet3 = new DefaultVirtualNetwork(networkId3, tenantId3);
+    private final VirtualNetwork vnet4 = new DefaultVirtualNetwork(networkId4, tenantId3);
+
+    private final DeviceId devId1 = DeviceId.deviceId("devid1");
+    private final DeviceId devId2 = DeviceId.deviceId("devid2");
+    private final DeviceId devId22 = DeviceId.deviceId("dev22");
+
+    private final VirtualDevice vdev1 = new DefaultVirtualDevice(networkId3, devId1);
+    private final VirtualDevice vdev2 = new DefaultVirtualDevice(networkId3, devId2);
+
+    private final Device dev1 = NetTestTools.device("dev1");
+    private final Device dev2 = NetTestTools.device("dev2");
+    private final Device dev22 = NetTestTools.device("dev22");
+
+    private final ConnectPoint cp1 = new ConnectPoint(dev1.id(), portNumber(1));
+    private final ConnectPoint cp2 = new ConnectPoint(dev2.id(), portNumber(2));
+
+    private final VirtualPort vport22 = new DefaultVirtualPort(networkId3,
+                                                               dev22, portNumber(22), cp1);
+    private final VirtualPort vport23 = new DefaultVirtualPort(networkId3,
+                                                               dev22, portNumber(23), cp2);
+
+    private final ConnectPoint cp11 = NetTestTools.connectPoint(devId1.toString(), 21);
+    private final ConnectPoint cp21 = NetTestTools.connectPoint(devId2.toString(), 22);
+    private final ConnectPoint cp12 = NetTestTools.connectPoint(devId1.toString(), 2);
+    private final ConnectPoint cp22 = NetTestTools.connectPoint(devId2.toString(), 22);
+
+    private final VirtualLink vlink1 = DefaultVirtualLink.builder()
+            .networkId(networkId3)
+            .src(cp22)
+            .dst(cp11)
+            .build();
+
+    private final VirtualLink vlink2 = DefaultVirtualLink.builder()
+            .networkId(networkId3)
+            .src(cp12)
+            .dst(cp21)
+            .build();
+
+    private final MacAddress mac1 = MacAddress.valueOf("00:11:00:00:00:01");
+    private final MacAddress mac2 = MacAddress.valueOf("00:22:00:00:00:02");
+    private final VlanId vlan1 = VlanId.vlanId((short) 11);
+    private final VlanId vlan2 = VlanId.vlanId((short) 22);
+    private final IpAddress ip1 = IpAddress.valueOf("10.0.0.1");
+    private final IpAddress ip2 = IpAddress.valueOf("10.0.0.2");
+    private final IpAddress ip3 = IpAddress.valueOf("10.0.0.3");
+
+    private final HostId hId1 = HostId.hostId(mac1, vlan1);
+    private final HostId hId2 = HostId.hostId(mac2, vlan2);
+    private final HostLocation loc1 = new HostLocation(devId1, portNumber(100), 123L);
+    private final HostLocation loc2 = new HostLocation(devId2, portNumber(200), 123L);
+    private final Set<IpAddress> ipSet1 = Sets.newHashSet(ip1, ip2);
+    private final Set<IpAddress> ipSet2 = Sets.newHashSet(ip1, ip3);
+    private final VirtualHost vhost1 = new DefaultVirtualHost(networkId1, hId1,
+                                                              mac1, vlan1, loc1, ipSet1);
+    private final VirtualHost vhost2 = new DefaultVirtualHost(networkId2, hId2,
+                                                              mac2, vlan2, loc2, ipSet2);
+
+
+
+
+    /**
+     * Sets up the global values for all the tests.
+     */
+    @Before
+    public void setUpTest() {
+        // Register the services needed for the test
+        codecService = new CodecManager();
+        codecService.activate();
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(VirtualNetworkAdminService.class, mockVnetAdminService)
+                        .add(VirtualNetworkService.class, mockVnetService)
+                        .add(CodecService.class, codecService);
+
+        setServiceDirectory(testDirectory);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual network entity representation in JSON matches
+     * the actual virtual network entity.
+     */
+    private static final class JsonObjectMatcher<T> extends TypeSafeMatcher<JsonObject> {
+        private final T vnetEntity;
+        private List<String> jsonFieldNames;
+        private String reason = "";
+        private BiFunction<T, String, String> getValue; // get vnetEntity's value
+
+        private JsonObjectMatcher(T vnetEntityValue,
+                                  List<String> jsonFieldNames1,
+                                  BiFunction<T, String, String> getValue1) {
+            vnetEntity = vnetEntityValue;
+            jsonFieldNames = jsonFieldNames1;
+            getValue = getValue1;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonHost) {
+            return jsonFieldNames
+                    .stream()
+                    .allMatch(s -> checkField(jsonHost, s, getValue.apply(vnetEntity, s)));
+        }
+
+        private boolean checkField(JsonObject jsonHost, String jsonFieldName,
+                                   String objectValue) {
+            final String jsonValue = jsonHost.get(jsonFieldName).asString();
+            if (!jsonValue.equals(objectValue)) {
+                reason = jsonFieldName + " " + objectValue;
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual network id array matcher.
+     *
+     * @param obj virtual network id object we are looking for
+     * @return matcher
+     */
+    /**
+     * Factory to allocate a virtual network entity matcher.
+     *
+     * @param obj            virtual network object we are looking for
+     * @param jsonFieldNames JSON field names to check against
+     * @param getValue       function to retrieve value from virtual network object
+     * @param <T>            the type of virtual network object
+     * @return matcher
+     */
+    private static <T> JsonObjectMatcher matchesVnetEntity(T obj, List<String> jsonFieldNames,
+                                                           BiFunction<T, String, String> getValue) {
+        return new JsonObjectMatcher<T>(obj, jsonFieldNames, getValue);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual network entity is represented properly in a JSON
+     * array of virtual network entities.
+     */
+    protected static class JsonArrayMatcher<T> extends TypeSafeMatcher<JsonArray> {
+        private final T vnetEntity;
+        private String reason = "";
+        private Function<T, String> getKey; // gets vnetEntity's key
+        private BiPredicate<T, JsonObject> checkKey; // check vnetEntity's key with JSON rep'n
+        private List<String> jsonFieldNames; // field/property names
+        private BiFunction<T, String, String> getValue; // get vnetEntity's value
+
+        protected JsonArrayMatcher(T vnetEntityValue, Function<T, String> getKey1,
+                                   BiPredicate<T, JsonObject> checkKey1,
+                                   List<String> jsonFieldNames1,
+                                   BiFunction<T, String, String> getValue1) {
+            vnetEntity = vnetEntityValue;
+            getKey = getKey1;
+            checkKey = checkKey1;
+            jsonFieldNames = jsonFieldNames1;
+            getValue = getValue1;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            boolean itemFound = false;
+            final int expectedAttributes = jsonFieldNames.size();
+            for (int jsonArrayIndex = 0; jsonArrayIndex < json.size();
+                 jsonArrayIndex++) {
+
+                final JsonObject jsonHost = json.get(jsonArrayIndex).asObject();
+
+                if (jsonHost.names().size() < expectedAttributes) {
+                    reason = "Found a virtual network with the wrong number of attributes";
+                    return false;
+                }
+
+                if (checkKey != null && checkKey.test(vnetEntity, jsonHost)) {
+                    itemFound = true;
+                    assertThat(jsonHost, matchesVnetEntity(vnetEntity, jsonFieldNames, getValue));
+                }
+            }
+            if (!itemFound) {
+                reason = getKey.apply(vnetEntity) + " was not found";
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Array matcher for VirtualNetwork.
+     */
+    private static final class VnetJsonArrayMatcher extends JsonArrayMatcher<VirtualNetwork> {
+
+        private VnetJsonArrayMatcher(VirtualNetwork vnetIn) {
+            super(vnetIn,
+                  vnet -> "Virtual network " + vnet.id().toString(),
+                  (vnet, jsonObject) -> jsonObject.get(ID).asString().equals(vnet.id().toString()),
+                  ImmutableList.of(ID, TENANT_ID),
+                  (vnet, s) -> s.equals(ID) ? vnet.id().toString()
+                          : s.equals(TENANT_ID) ? vnet.tenantId().toString()
+                          : null
+            );
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual network array matcher.
+     *
+     * @param vnet virtual network object we are looking for
+     * @return matcher
+     */
+    private VnetJsonArrayMatcher hasVnet(VirtualNetwork vnet) {
+        return new VnetJsonArrayMatcher(vnet);
+    }
+
+    // Tests for Virtual Networks
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual networks.
+     */
+    @Test
+    public void testGetVirtualNetworksEmptyArray() {
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetAdminService);
+        expect(mockVnetService.getVirtualNetworks(tenantId4)).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String response = wt.path("vnets").request().get(String.class);
+        assertThat(response, is("{\"vnets\":[]}"));
+
+        verify(mockVnetService);
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual networks are defined.
+     */
+    @Test
+    public void testGetVirtualNetworksArray() {
+        final Set<VirtualNetwork> vnetSet = ImmutableSet.of(vnet1, vnet2, vnet3, vnet4);
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes();
+        replay(mockVnetAdminService);
+        expect(mockVnetService.getVirtualNetworks(tenantId3)).andReturn(vnetSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String response = wt.path("vnets").request().get(String.class);
+        assertThat(response, containsString("{\"vnets\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("vnets"));
+
+        final JsonArray vnetJsonArray = result.get("vnets").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual networks array is not the correct size.",
+                     vnetSet.size(), vnetJsonArray.size());
+
+        vnetSet.forEach(vnet -> assertThat(vnetJsonArray, hasVnet(vnet)));
+
+        verify(mockVnetService);
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests the result of the REST API GET for virtual networks with tenant id.
+     */
+    @Test
+    public void testGetVirtualNetworksByTenantId() {
+        final Set<VirtualNetwork> vnetSet = ImmutableSet.of(vnet1, vnet2, vnet3, vnet4);
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes();
+        replay(mockVnetAdminService);
+        expect(mockVnetService.getVirtualNetworks(tenantId3)).andReturn(vnetSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String response = wt.path("vnets/" + tenantId3.id()).request().get(String.class);
+        assertThat(response, containsString("{\"vnets\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("vnets"));
+
+        final JsonArray vnetJsonArray = result.get("vnets").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual networks array is not the correct size.",
+                     vnetSet.size(), vnetJsonArray.size());
+
+        vnetSet.forEach(vnet -> assertThat(vnetJsonArray, hasVnet(vnet)));
+
+        verify(mockVnetService);
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests the result of the REST API GET for virtual networks with tenant id.
+     */
+    @Test
+    public void testGetVirtualNetworksByNonExistentTenantId() {
+        String tenantIdName = "NON_EXISTENT_TENANT_ID";
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes();
+        replay(mockVnetAdminService);
+        expect(mockVnetService.getVirtualNetworks(anyObject())).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+
+        try {
+            wt.path("vnets/" + tenantIdName)
+                    .request()
+                    .get(String.class);
+            fail("Get of a non-existent virtual network did not throw an exception");
+        } catch (NotFoundException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
+        }
+
+        verify(mockVnetService);
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of new virtual network using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualNetwork() {
+        expect(mockVnetAdminService.createVirtualNetwork(tenantId2)).andReturn(vnet1);
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = TenantWebResourceTest.class
+                .getResourceAsStream("post-tenant.json");
+
+        Response response = wt.path("vnets").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/vnets/" + vnet1.id().toString()));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual network using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualNetworkNullTenantId() {
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            wt.path("vnets")
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual network did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual network with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualNetwork() {
+        mockVnetAdminService.removeVirtualNetwork(anyObject());
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        Response response = wt.path("vnets/" + "2")
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests that a DELETE of a non-existent virtual network throws an exception.
+     */
+    @Test
+    public void testDeleteNetworkNonExistentNetworkId() {
+        expect(mockVnetAdminService.getTenantIds())
+                .andReturn(ImmutableSet.of())
+                .anyTimes();
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+
+        try {
+            wt.path("vnets/" + "NON_EXISTENT_NETWORK_ID")
+                    .request()
+                    .delete(String.class);
+            fail("Delete of a non-existent virtual network did not throw an exception");
+        } catch (NotFoundException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    // Tests for Virtual Device
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual devices.
+     */
+    @Test
+    public void testGetVirtualDevicesEmptyArray() {
+        NetworkId networkId = networkId4;
+        expect(mockVnetService.getVirtualDevices(networkId)).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/devices";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, is("{\"devices\":[]}"));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual devices are defined.
+     */
+    @Test
+    public void testGetVirtualDevicesArray() {
+        NetworkId networkId = networkId3;
+        vdevSet.add(vdev1);
+        vdevSet.add(vdev2);
+        expect(mockVnetService.getVirtualDevices(networkId)).andReturn(vdevSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/devices";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, containsString("{\"devices\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("devices"));
+
+        final JsonArray vnetJsonArray = result.get("devices").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual devices array is not the correct size.",
+                     vdevSet.size(), vnetJsonArray.size());
+
+        vdevSet.forEach(vdev -> assertThat(vnetJsonArray, hasVdev(vdev)));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Array matcher for VirtualDevice.
+     */
+    private static final class VdevJsonArrayMatcher extends JsonArrayMatcher<VirtualDevice> {
+
+        private VdevJsonArrayMatcher(VirtualDevice vdevIn) {
+            super(vdevIn,
+                  vdev -> "Virtual device " + vdev.networkId().toString()
+                          + " " + vdev.id().toString(),
+                  (vdev, jsonObject) -> jsonObject.get(ID).asString().equals(vdev.networkId().toString())
+                          && jsonObject.get(DEVICE_ID).asString().equals(vdev.id().toString()),
+                  ImmutableList.of(ID, DEVICE_ID),
+                  (vdev, s) -> s.equals(ID) ? vdev.networkId().toString()
+                          : s.equals(DEVICE_ID) ? vdev.id().toString()
+                          : null
+            );
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual device array matcher.
+     *
+     * @param vdev virtual device object we are looking for
+     * @return matcher
+     */
+    private VdevJsonArrayMatcher hasVdev(VirtualDevice vdev) {
+        return new VdevJsonArrayMatcher(vdev);
+    }
+    /**
+     * Tests adding of new virtual device using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualDevice() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        expect(mockVnetAdminService.createVirtualDevice(networkId, deviceId)).andReturn(vdev2);
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-device.json");
+        String reqLocation = "vnets/" + networkId.toString() + "/devices";
+        Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/" + reqLocation + "/" + vdev2.id().toString()));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual device using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualDeviceNullJsonStream() {
+        NetworkId networkId = networkId3;
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String reqLocation = "vnets/" + networkId.toString() + "/devices";
+            wt.path(reqLocation)
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual device did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual device with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualDevice() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        mockVnetAdminService.removeVirtualDevice(networkId, deviceId);
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        String reqLocation = "vnets/" + networkId.toString() + "/devices/" + deviceId.toString();
+        Response response = wt.path(reqLocation)
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+
+        verify(mockVnetAdminService);
+    }
+
+    // Tests for Virtual Ports
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual ports.
+     */
+    @Test
+    public void testGetVirtualPortsEmptyArray() {
+        NetworkId networkId = networkId4;
+        DeviceId deviceId = devId2;
+        expect(mockVnetService.getVirtualPorts(networkId, deviceId))
+                .andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString()
+                + "/devices/" + deviceId.toString() + "/ports";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, is("{\"ports\":[]}"));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual ports are defined.
+     */
+    @Test
+    public void testGetVirtualPortsArray() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = dev22.id();
+        vportSet.add(vport23);
+        vportSet.add(vport22);
+        expect(mockVnetService.getVirtualPorts(networkId, deviceId)).andReturn(vportSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString()
+                + "/devices/" + deviceId.toString() + "/ports";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, containsString("{\"ports\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("ports"));
+
+        final JsonArray vnetJsonArray = result.get("ports").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual ports array is not the correct size.",
+                     vportSet.size(), vnetJsonArray.size());
+
+        vportSet.forEach(vport -> assertThat(vnetJsonArray, hasVport(vport)));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Array matcher for VirtualPort.
+     */
+    private static final class VportJsonArrayMatcher extends JsonArrayMatcher<VirtualPort> {
+
+        private VportJsonArrayMatcher(VirtualPort vportIn) {
+            super(vportIn,
+                  vport -> "Virtual port " + vport.networkId().toString() + " "
+                    + vport.element().id().toString() + " " + vport.number().toString(),
+                  (vport, jsonObject) -> jsonObject.get(ID).asString().equals(vport.networkId().toString())
+                          && jsonObject.get(PORT_NUM).asString().equals(vport.number().toString())
+                          && jsonObject.get(DEVICE_ID).asString().equals(vport.element().id().toString()),
+                  ImmutableList.of(ID, DEVICE_ID, PORT_NUM, PHYS_DEVICE_ID, PHYS_PORT_NUM),
+                  (vport, s) -> s.equals(ID) ? vport.networkId().toString()
+                          : s.equals(DEVICE_ID) ? vport.element().id().toString()
+                          : s.equals(PORT_NUM) ? vport.number().toString()
+                          : s.equals(PHYS_DEVICE_ID) ? vport.realizedBy().deviceId().toString()
+                          : s.equals(PHYS_PORT_NUM) ? vport.realizedBy().port().toString()
+                          : null
+            );
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual port array matcher.
+     *
+     * @param vport virtual port object we are looking for
+     * @return matcher
+     */
+    private VportJsonArrayMatcher hasVport(VirtualPort vport) {
+        return new VportJsonArrayMatcher(vport);
+    }
+
+    /**
+     * Tests adding of new virtual port using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualPort() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId22;
+        DefaultAnnotations annotations = DefaultAnnotations.builder().build();
+        Device physDevice = new DefaultDevice(null, DeviceId.deviceId("dev1"),
+                                              null, null, null, null, null, null, annotations);
+        ConnectPoint cp1 = new ConnectPoint(physDevice.id(), portNumber(1));
+        expect(mockVnetAdminService.createVirtualPort(networkId, deviceId, portNumber(22), cp1))
+                .andReturn(vport22);
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-port.json");
+        String reqLocation = "vnets/" + networkId.toString()
+                + "/devices/" + deviceId.toString() + "/ports";
+        Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual port using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualPortNullJsonStream() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String reqLocation = "vnets/" + networkId.toString()
+                    + "/devices/" + deviceId.toString() + "/ports";
+            wt.path(reqLocation)
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual port did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual port with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualPort() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        PortNumber portNum = portNumber(2);
+        mockVnetAdminService.removeVirtualPort(networkId, deviceId, portNum);
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        String reqLocation = "vnets/" + networkId.toString()
+                + "/devices/" + deviceId.toString() + "/ports/" + portNum.toLong();
+        Response response = wt.path(reqLocation)
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+
+        verify(mockVnetAdminService);
+    }
+
+    // Tests for Virtual Links
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual links.
+     */
+    @Test
+    public void testGetVirtualLinksEmptyArray() {
+        NetworkId networkId = networkId4;
+        expect(mockVnetService.getVirtualLinks(networkId)).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/links";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, is("{\"links\":[]}"));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual links are defined.
+     */
+    @Test
+    public void testGetVirtualLinksArray() {
+        NetworkId networkId = networkId3;
+        final Set<VirtualLink> vlinkSet = ImmutableSet.of(vlink1, vlink2);
+        expect(mockVnetService.getVirtualLinks(networkId)).andReturn(vlinkSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/links";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, containsString("{\"links\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("links"));
+
+        final JsonArray vnetJsonArray = result.get("links").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual links array is not the correct size.",
+                     vlinkSet.size(), vnetJsonArray.size());
+
+        vlinkSet.forEach(vlink -> assertThat(vnetJsonArray, hasVlink(vlink)));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual link representation in JSON matches
+     * the actual virtual link.
+     */
+    private static final class VirtualLinkJsonMatcher extends LinksResourceTest.LinkJsonMatcher {
+        private final VirtualLink vlink;
+        private String reason = "";
+
+        private VirtualLinkJsonMatcher(VirtualLink vlinkValue) {
+            super(vlinkValue);
+            vlink = vlinkValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonLink) {
+            if (!super.matchesSafely(jsonLink)) {
+                return false;
+            }
+            // check NetworkId
+            String jsonNetworkId = jsonLink.get(ID).asString();
+            String networkId = vlink.networkId().toString();
+            if (!jsonNetworkId.equals(networkId)) {
+                reason = ID + " was " + jsonNetworkId;
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual link matcher.
+     *
+     * @param vlink virtual link object we are looking for
+     * @return matcher
+     */
+    private static VirtualLinkJsonMatcher matchesVirtualLink(VirtualLink vlink) {
+        return new VirtualLinkJsonMatcher(vlink);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual link is represented properly in a JSON
+     * array of links.
+     */
+    private static final class VirtualLinkJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+        private final VirtualLink vlink;
+        private String reason = "";
+
+        private VirtualLinkJsonArrayMatcher(VirtualLink vlinkValue) {
+            vlink = vlinkValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            for (int jsonLinkIndex = 0; jsonLinkIndex < json.size();
+                 jsonLinkIndex++) {
+
+                JsonObject jsonLink = json.get(jsonLinkIndex).asObject();
+
+                if (matchesVirtualLink(vlink).matchesSafely(jsonLink)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual link array matcher.
+     *
+     * @param vlink virtual link object we are looking for
+     * @return matcher
+     */
+    private VirtualLinkJsonArrayMatcher hasVlink(VirtualLink vlink) {
+        return new VirtualLinkJsonArrayMatcher(vlink);
+    }
+
+    /**
+     * Tests adding of new virtual link using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualLink() {
+        NetworkId networkId = networkId3;
+        expect(mockVnetAdminService.createVirtualLink(networkId, cp22, cp11))
+                .andReturn(vlink1);
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-link.json");
+        String reqLocation = "vnets/" + networkId.toString() + "/links";
+        Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/" + reqLocation));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual link using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualLinkNullJsonStream() {
+        NetworkId networkId = networkId3;
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String reqLocation = "vnets/" + networkId.toString() + "/links";
+            wt.path(reqLocation)
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual link did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual link with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualLink() {
+        NetworkId networkId = networkId3;
+        mockVnetAdminService.removeVirtualLink(networkId, cp22, cp11);
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-link.json");
+        String reqLocation = "vnets/" + networkId.toString() + "/links";
+        Response response = wt.path(reqLocation).request().method("DELETE", Entity.json(jsonStream));
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+        verify(mockVnetAdminService);
+    }
+
+    // Tests for Virtual Hosts
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual hosts.
+     */
+    @Test
+    public void testGetVirtualHostsEmptyArray() {
+        NetworkId networkId = networkId4;
+        expect(mockVnetService.getVirtualHosts(networkId)).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/hosts";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, is("{\"hosts\":[]}"));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual hosts are defined.
+     */
+    @Test
+    public void testGetVirtualHostsArray() {
+        NetworkId networkId = networkId3;
+        final Set<VirtualHost> vhostSet = ImmutableSet.of(vhost1, vhost2);
+        expect(mockVnetService.getVirtualHosts(networkId)).andReturn(vhostSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/hosts";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, containsString("{\"hosts\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("hosts"));
+
+        final JsonArray vnetJsonArray = result.get("hosts").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual hosts array is not the correct size.",
+                     vhostSet.size(), vnetJsonArray.size());
+
+        vhostSet.forEach(vhost -> assertThat(vnetJsonArray, hasVhost(vhost)));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual host representation in JSON matches
+     * the actual virtual host.
+     */
+    private static final class VirtualHostJsonMatcher extends HostResourceTest.HostJsonMatcher {
+        private final VirtualHost vhost;
+        private String reason = "";
+
+        private VirtualHostJsonMatcher(VirtualHost vhostValue) {
+            super(vhostValue);
+            vhost = vhostValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonHost) {
+            if (!super.matchesSafely(jsonHost)) {
+                return false;
+            }
+            // check NetworkId
+            String jsonNetworkId = jsonHost.get(ID).asString();
+            String networkId = vhost.networkId().toString();
+            if (!jsonNetworkId.equals(networkId)) {
+                reason = ID + " was " + jsonNetworkId;
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual host matcher.
+     *
+     * @param vhost virtual host object we are looking for
+     * @return matcher
+     */
+    private static VirtualHostJsonMatcher matchesVirtualHost(VirtualHost vhost) {
+        return new VirtualHostJsonMatcher(vhost);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual host is represented properly in a JSON
+     * array of hosts.
+     */
+    private static final class VirtualHostJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+        private final VirtualHost vhost;
+        private String reason = "";
+
+        private VirtualHostJsonArrayMatcher(VirtualHost vhostValue) {
+            vhost = vhostValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            for (int jsonHostIndex = 0; jsonHostIndex < json.size();
+                 jsonHostIndex++) {
+
+                JsonObject jsonHost = json.get(jsonHostIndex).asObject();
+
+                if (matchesVirtualHost(vhost).matchesSafely(jsonHost)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual host array matcher.
+     *
+     * @param vhost virtual host object we are looking for
+     * @return matcher
+     */
+    private VirtualHostJsonArrayMatcher hasVhost(VirtualHost vhost) {
+        return new VirtualHostJsonArrayMatcher(vhost);
+    }
+
+    /**
+     * Tests adding of new virtual host using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualHost() {
+        NetworkId networkId = networkId3;
+        expect(mockVnetAdminService.createVirtualHost(networkId, hId1, mac1, vlan1, loc1, ipSet1))
+                .andReturn(vhost1);
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-host.json");
+        String reqLocation = "vnets/" + networkId.toString() + "/hosts";
+        Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/" + reqLocation));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual host using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualHostNullJsonStream() {
+        NetworkId networkId = networkId3;
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String reqLocation = "vnets/" + networkId.toString() + "/hosts";
+            wt.path(reqLocation)
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual host did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual host with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualHost() {
+        NetworkId networkId = networkId3;
+        mockVnetAdminService.removeVirtualHost(networkId, hId1);
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-host.json");
+        String reqLocation = "vnets/" + networkId.toString() + "/hosts";
+        Response response = wt.path(reqLocation).request().method("DELETE", Entity.json(jsonStream));
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
+        verify(mockVnetAdminService);
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMastershipStoreTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMastershipStoreTest.java
new file mode 100644
index 0000000..58d3506
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/store/impl/SimpleVirtualMastershipStoreTest.java
@@ -0,0 +1,207 @@
+/*
+ * 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.onosproject.incubator.net.virtual.store.impl;
+
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Futures;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipTerm;
+import org.onosproject.net.DeviceId;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.mastership.MastershipEvent.Type.MASTER_CHANGED;
+import static org.onosproject.net.MastershipRole.MASTER;
+import static org.onosproject.net.MastershipRole.NONE;
+import static org.onosproject.net.MastershipRole.STANDBY;
+
+public class SimpleVirtualMastershipStoreTest {
+
+    private static final NetworkId VNID1 = NetworkId.networkId(1);
+
+    private static final DeviceId VDID1 = DeviceId.deviceId("of:01");
+    private static final DeviceId VDID2 = DeviceId.deviceId("of:02");
+    private static final DeviceId VDID3 = DeviceId.deviceId("of:03");
+    private static final DeviceId VDID4 = DeviceId.deviceId("of:04");
+
+    private static final NodeId N1 = new NodeId("local");
+    private static final NodeId N2 = new NodeId("other");
+
+    private SimpleVirtualMastershipStore sms;
+
+    @Before
+    public void setUp() throws Exception {
+        sms = new SimpleVirtualMastershipStore();
+        sms.activate();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        sms.deactivate();
+    }
+
+    @Test
+    public void getRole() {
+        //special case, no backup or master
+        put(VNID1, VDID1, N1, false, false);
+        assertEquals("wrong role", NONE, sms.getRole(VNID1, N1, VDID1));
+
+        //backup exists but we aren't mapped
+        put(VNID1, VDID2, N1, false, true);
+        assertEquals("wrong role", STANDBY, sms.getRole(VNID1, N1, VDID2));
+
+        //N2 is master
+        put(VNID1, VDID3, N2, true, true);
+        assertEquals("wrong role", MASTER, sms.getRole(VNID1, N2, VDID3));
+
+        //N2 is master but N1 is only in backups set
+        put(VNID1, VDID4, N1, false, true);
+        put(VNID1, VDID4, N2, true, false);
+        assertEquals("wrong role", STANDBY, sms.getRole(VNID1, N1, VDID4));
+    }
+
+    @Test
+    public void getMaster() {
+        put(VNID1, VDID3, N2, true, true);
+        assertEquals("wrong role", MASTER, sms.getRole(VNID1, N2, VDID3));
+        assertEquals("wrong node", N2, sms.getMaster(VNID1, VDID3));
+    }
+
+    @Test
+    public void setMaster() {
+        put(VNID1, VDID1, N1, false, false);
+        assertEquals("wrong event", MASTER_CHANGED,
+                     Futures.getUnchecked(sms.setMaster(VNID1, N1, VDID1)).type());
+        assertEquals("wrong role", MASTER, sms.getRole(VNID1, N1, VDID1));
+        //set node that's already master - should be ignored
+        assertNull("wrong event",
+                   Futures.getUnchecked(sms.setMaster(VNID1, N1, VDID1)));
+
+        //set STANDBY to MASTER
+        put(VNID1, VDID2, N1, false, true);
+        assertEquals("wrong role", STANDBY, sms.getRole(VNID1, N1, VDID2));
+        assertEquals("wrong event", MASTER_CHANGED,
+                     Futures.getUnchecked(sms.setMaster(VNID1, N1, VDID2)).type());
+        assertEquals("wrong role", MASTER, sms.getRole(VNID1, N1, VDID2));
+    }
+
+    @Test
+    public void getDevices() {
+        Set<DeviceId> d = Sets.newHashSet(VDID1, VDID2);
+
+        put(VNID1, VDID1, N2, true, true);
+        put(VNID1, VDID2, N2, true, true);
+        put(VNID1, VDID3, N1, true, true);
+        assertTrue("wrong devices", d.equals(sms.getDevices(VNID1, N2)));
+    }
+
+    @Test
+    public void getTermFor() {
+        put(VNID1, VDID1, N1, true, true);
+        assertEquals("wrong term", MastershipTerm.of(N1, 0),
+                     sms.getTermFor(VNID1, VDID1));
+
+        //switch to N2 and back - 2 term switches
+        sms.setMaster(VNID1, N2, VDID1);
+        sms.setMaster(VNID1, N1, VDID1);
+        assertEquals("wrong term", MastershipTerm.of(N1, 2),
+                     sms.getTermFor(VNID1, VDID1));
+    }
+
+    @Test
+    public void requestRole() {
+        //NONE - become MASTER
+        put(VNID1, VDID1, N1, false, false);
+        assertEquals("wrong role", MASTER,
+                     Futures.getUnchecked(sms.requestRole(VNID1, VDID1)));
+
+        //was STANDBY - become MASTER
+        put(VNID1, VDID2, N1, false, true);
+        assertEquals("wrong role", MASTER,
+                     Futures.getUnchecked(sms.requestRole(VNID1, VDID2)));
+
+        //other MASTER - stay STANDBY
+        put(VNID1, VDID3, N2, true, false);
+        assertEquals("wrong role", STANDBY,
+                     Futures.getUnchecked(sms.requestRole(VNID1, VDID3)));
+
+        //local (N1) is MASTER - stay MASTER
+        put(VNID1, VDID4, N1, true, true);
+        assertEquals("wrong role", MASTER,
+                     Futures.getUnchecked(sms.requestRole(VNID1, VDID4)));
+    }
+
+    @Test
+    public void unsetMaster() {
+        //NONE - record backup but take no other action
+        put(VNID1, VDID1, N1, false, false);
+        sms.setStandby(VNID1, N1, VDID1);
+        assertTrue("not backed up", sms.backupsByNetwork.get(VNID1)
+                .get(VDID1).contains(N1));
+        int prev = sms.termMapByNetwork.get(VNID1).get(VDID1).get();
+        sms.setStandby(VNID1, N1, VDID1);
+        assertEquals("term should not change", prev, sms.termMapByNetwork.get(VNID1)
+                .get(VDID1).get());
+
+        //no backup, MASTER
+        put(VNID1, VDID1, N1, true, false);
+        assertNull("expect no MASTER event",
+                   Futures.getUnchecked(sms.setStandby(VNID1, N1, VDID1)).roleInfo().master());
+        assertNull("wrong node", sms.masterMapByNetwork.get(VNID1).get(VDID1));
+
+        //backup, switch
+        sms.masterMapByNetwork.get(VNID1).clear();
+        put(VNID1, VDID1, N1, true, true);
+        put(VNID1, VDID1, N2, false, true);
+        put(VNID1, VDID2, N2, true, true);
+        MastershipEvent event = Futures.getUnchecked(sms.setStandby(VNID1, N1, VDID1));
+        assertEquals("wrong event", MASTER_CHANGED, event.type());
+        assertEquals("wrong master", N2, event.roleInfo().master());
+    }
+
+    //helper to populate master/backup structures
+    private void put(NetworkId networkId, DeviceId dev, NodeId node,
+                     boolean master, boolean backup) {
+        if (master) {
+            sms.masterMapByNetwork
+                    .computeIfAbsent(networkId, k -> new HashMap<>())
+                    .put(dev, node);
+        } else if (backup) {
+            List<NodeId> stbys = sms.backupsByNetwork
+                    .computeIfAbsent(networkId, k -> new HashMap<>())
+                    .getOrDefault(dev, new ArrayList<>());
+            stbys.add(node);
+            sms.backupsByNetwork.get(networkId).put(dev, stbys);
+        }
+
+        sms.termMapByNetwork
+                .computeIfAbsent(networkId, k -> new HashMap<>())
+                .put(dev, new AtomicInteger());
+    }
+}
\ No newline at end of file
