Detangling incubator: virtual nets, tunnels, resource labels, oh my
- virtual networking moved to /apps/virtual; with CLI & REST API
- tunnels and labels moved to /apps/tunnel; with CLI & REST API; UI disabled for now
- protobuf/models moved to /core/protobuf/models
- defunct grpc/rpc registry stuff left under /graveyard
- compile dependencies on /incubator moved to respective modules for compilation
- run-time dependencies will need to be re-tested for dependent apps
- /graveyard will be removed in not-too-distant future
Change-Id: I0a0b995c635487edcf95a352f50dd162186b0b39
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
diff --git a/apps/virtual/app/src/test/resources/domain-config.json b/apps/virtual/app/src/test/resources/domain-config.json
new file mode 100644
index 0000000..beda11a
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/domain-config.json
@@ -0,0 +1,36 @@
+{
+ "domains" : {
+ "cord" : {
+ "basic" : {
+ "name" : "Core Fabric",
+ "applicationName" : "org.onosproject.testdomain",
+ "internalDevices" : [ "of:1" ],
+ "edgePorts" : [ "of:12/1", "of:14/1" ]
+ }
+ },
+ "mpls" : {
+ "basic" : {
+ "name" : "MPLS Core",
+ "applicationName" : "org.onosproject.testdomain",
+ "internalDevices" : [ "of:2" ],
+ "edgePorts" : [ "of:12/2", "of:23/2" ]
+ }
+ },
+ "dc" : {
+ "basic" : {
+ "name" : "Data Center Fabric",
+ "applicationName" : "org.onosproject.testdomain",
+ "internalDevices" : [ "of:3" ],
+ "edgePorts" : [ "of:23/3", "of:34/3" ]
+ }
+ },
+ "optical" : {
+ "basic" : {
+ "name" : "Optical Core",
+ "applicationName" : "org.onosproject.testdomain",
+ "internalDevices" : [ "of:4" ],
+ "edgePorts" : [ "of:14/4", "of:34/4" ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/resources/fractal-domain-config.json b/apps/virtual/app/src/test/resources/fractal-domain-config.json
new file mode 100644
index 0000000..521c840
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/fractal-domain-config.json
@@ -0,0 +1,28 @@
+{
+ "domains" : {
+ "domain1" : {
+ "basic" : {
+ "name" : "Domain 1",
+ "applicationName" : "org.onosproject.meshdomain",
+ "internalDevices" : [ "of:0000000000001001", "of:0000000000001002", "of:0000000000001003" ],
+ "edgePorts" : [ "of:0000000000010000/1", "of:0000000003010000/2", "of:0000000002010000/1" ]
+ }
+ },
+ "domain2" : {
+ "basic" : {
+ "name" : "Domain 2",
+ "applicationName" : "org.onosproject.meshdomain",
+ "internalDevices" : [ "of:0000000000002001", "of:0000000000002002", "of:0000000000002003" ],
+ "edgePorts" : [ "of:0000000000020000/1", "of:0000000003020000/1", "of:0000000002010000/2" ]
+ }
+ },
+ "domain3" : {
+ "basic" : {
+ "name" : "Domain 3",
+ "applicationName" : "org.onosproject.meshdomain",
+ "internalDevices" : [ "of:0000000000003001", "of:0000000000003002", "of:0000000000003003" ],
+ "edgePorts" : [ "of:0000000000030000/1", "of:0000000003010000/1", "of:0000000003020000/2" ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-tenant.json b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-tenant.json
new file mode 100644
index 0000000..407f9a2
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-tenant.json
@@ -0,0 +1,3 @@
+{
+ "id": "TenantId2"
+}
diff --git a/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-device.json b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-device.json
new file mode 100644
index 0000000..fbd129c
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-device.json
@@ -0,0 +1,4 @@
+{
+ "networkId": "3",
+ "deviceId": "devId2"
+}
diff --git a/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-host.json b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-host.json
new file mode 100644
index 0000000..557dc32
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-host.json
@@ -0,0 +1,16 @@
+{
+ "networkId": "3",
+ "id": "00:11:00:00:00:01/11",
+ "mac": "00:11:00:00:00:01",
+ "vlan": "11",
+ "locations": [
+ {
+ "elementId": "devid1",
+ "port": "100"
+ }
+ ],
+ "ipAddresses": [
+ "10.0.0.1",
+ "10.0.0.2"
+ ]
+}
diff --git a/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-link.json b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-link.json
new file mode 100644
index 0000000..8f04673
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-link.json
@@ -0,0 +1,13 @@
+{
+ "networkId": "3",
+ "src": {
+ "device": "of:devid2",
+ "port": "22"
+ },
+ "dst": {
+ "device": "of:devid1",
+ "port": "21"
+ },
+ "type": "VIRTUAL",
+ "state": "ACTIVE"
+}
diff --git a/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-port.json b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-port.json
new file mode 100644
index 0000000..1d60842
--- /dev/null
+++ b/apps/virtual/app/src/test/resources/org/onosproject/incubator/net/virtual/rest/post-virtual-port.json
@@ -0,0 +1,7 @@
+{
+ "networkId": "3",
+ "deviceId": "dev22",
+ "portNum": "22",
+ "physDeviceId": "dev1",
+ "physPortNum": "1"
+}