Finished unit tests for trivial link manager.
diff --git a/net/api/src/main/java/org/onlab/onos/net/link/DefaultLinkDescription.java b/net/api/src/main/java/org/onlab/onos/net/link/DefaultLinkDescription.java
index 952c1dc..ffdc2fa 100644
--- a/net/api/src/main/java/org/onlab/onos/net/link/DefaultLinkDescription.java
+++ b/net/api/src/main/java/org/onlab/onos/net/link/DefaultLinkDescription.java
@@ -37,7 +37,7 @@
@Override
public Link.Type type() {
- return null;
+ return type;
}
}
diff --git a/net/api/src/main/java/org/onlab/onos/net/link/LinkEvent.java b/net/api/src/main/java/org/onlab/onos/net/link/LinkEvent.java
index 18987ea..a85965a 100644
--- a/net/api/src/main/java/org/onlab/onos/net/link/LinkEvent.java
+++ b/net/api/src/main/java/org/onlab/onos/net/link/LinkEvent.java
@@ -18,6 +18,11 @@
LINK_ADDED,
/**
+ * Signifies that a link has been updated.
+ */
+ LINK_UPDATED,
+
+ /**
* Signifies that a link has been removed.
*/
LINK_REMOVED
diff --git a/net/api/src/main/java/org/onlab/onos/net/link/LinkService.java b/net/api/src/main/java/org/onlab/onos/net/link/LinkService.java
index 77afb7a..1257d97 100644
--- a/net/api/src/main/java/org/onlab/onos/net/link/LinkService.java
+++ b/net/api/src/main/java/org/onlab/onos/net/link/LinkService.java
@@ -48,7 +48,7 @@
* @param deviceId device identifier
* @return set of device ingress links
*/
- Set<Link> getDeviceInressLinks(DeviceId deviceId);
+ Set<Link> getDeviceIngressLinks(DeviceId deviceId);
/**
* Returns set of all infrastructure links leading to and from the
@@ -75,17 +75,17 @@
* @param connectPoint connection point
* @return set of device ingress links
*/
- Set<Link> getInressLinks(ConnectPoint connectPoint);
+ Set<Link> getIngressLinks(ConnectPoint connectPoint);
/**
- * Returns set of all infrastructure links between the specified source
+ * Returns the infrastructure links between the specified source
* and destination connection points.
*
* @param src source connection point
* @param dst destination connection point
- * @return set of links
+ * @return link from source to destination; null if none found
*/
- Set<Link> getLinks(ConnectPoint src, ConnectPoint dst);
+ Link getLink(ConnectPoint src, ConnectPoint dst);
/**
* Adds the specified link listener.
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java
index 63fb2cc..6e7c567 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java
@@ -93,7 +93,7 @@
}
@Override
- public Set<Link> getDeviceInressLinks(DeviceId deviceId) {
+ public Set<Link> getDeviceIngressLinks(DeviceId deviceId) {
checkNotNull(deviceId, DEVICE_ID_NULL);
return store.getDeviceIngressLinks(deviceId);
}
@@ -112,17 +112,16 @@
}
@Override
- public Set<Link> getInressLinks(ConnectPoint connectPoint) {
+ public Set<Link> getIngressLinks(ConnectPoint connectPoint) {
checkNotNull(connectPoint, CONNECT_POINT_NULL);
return store.getIngressLinks(connectPoint);
}
@Override
- public Set<Link> getLinks(ConnectPoint src, ConnectPoint dst) {
+ public Link getLink(ConnectPoint src, ConnectPoint dst) {
checkNotNull(src, CONNECT_POINT_NULL);
checkNotNull(dst, CONNECT_POINT_NULL);
- return Sets.intersection(store.getEgressLinks(src),
- store.getIngressLinks(dst));
+ return store.getLink(src, dst);
}
@Override
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java
index c1d6273..d10c3a4 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java
@@ -18,6 +18,12 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import static org.onlab.onos.net.Link.Type.DIRECT;
+import static org.onlab.onos.net.Link.Type.INDIRECT;
+import static org.onlab.onos.net.link.LinkEvent.Type.LINK_ADDED;
+import static org.onlab.onos.net.link.LinkEvent.Type.LINK_REMOVED;
+import static org.onlab.onos.net.link.LinkEvent.Type.LINK_UPDATED;
+
/**
* Manages inventory of infrastructure links using trivial in-memory link
* implementation.
@@ -72,6 +78,17 @@
}
/**
+ * Returns the link between the two end-points.
+ *
+ * @param src source connection point
+ * @param dst destination connection point
+ * @return link or null if one not found between the end-points
+ */
+ Link getLink(ConnectPoint src, ConnectPoint dst) {
+ return links.get(new LinkKey(src, dst));
+ }
+
+ /**
* Returns all links egressing from the specified connection point.
*
* @param src source connection point
@@ -96,14 +113,13 @@
Set<Link> getIngressLinks(ConnectPoint dst) {
Set<Link> ingress = new HashSet<>();
for (Link link : dstLinks.get(dst.deviceId())) {
- if (link.src().equals(dst)) {
+ if (link.dst().equals(dst)) {
ingress.add(link);
}
}
return ingress;
}
-
/**
* Creates a new link, or updates an existing one, based on the given
* information.
@@ -119,7 +135,7 @@
if (link == null) {
return createLink(providerId, key, linkDescription);
}
- return updateLink(link, linkDescription);
+ return updateLink(providerId, link, key, linkDescription);
}
// Creates and stores the link and returns the appropriate event.
@@ -132,11 +148,26 @@
srcLinks.put(link.src().deviceId(), link);
dstLinks.put(link.dst().deviceId(), link);
}
- return new LinkEvent(LinkEvent.Type.LINK_ADDED, link);
+ return new LinkEvent(LINK_ADDED, link);
}
// Updates, if necessary the specified link and returns the appropriate event.
- private LinkEvent updateLink(DefaultLink link, LinkDescription linkDescription) {
+ private LinkEvent updateLink(ProviderId providerId, DefaultLink link,
+ LinkKey key, LinkDescription linkDescription) {
+ if (link.type() == INDIRECT && linkDescription.type() == DIRECT) {
+ synchronized (this) {
+ srcLinks.remove(link.src().deviceId(), link);
+ dstLinks.remove(link.dst().deviceId(), link);
+
+ DefaultLink updated =
+ new DefaultLink(providerId, link.src(), link.dst(),
+ linkDescription.type());
+ links.put(key, updated);
+ srcLinks.put(link.src().deviceId(), updated);
+ dstLinks.put(link.dst().deviceId(), updated);
+ return new LinkEvent(LINK_UPDATED, updated);
+ }
+ }
return null;
}
@@ -150,9 +181,12 @@
LinkEvent removeLink(ConnectPoint src, ConnectPoint dst) {
synchronized (this) {
Link link = links.remove(new LinkKey(src, dst));
- srcLinks.remove(link.src().deviceId(), link);
- dstLinks.remove(link.dst().deviceId(), link);
- return link == null ? null : new LinkEvent(LinkEvent.Type.LINK_REMOVED, link);
+ if (link != null) {
+ srcLinks.remove(link.src().deviceId(), link);
+ dstLinks.remove(link.dst().deviceId(), link);
+ return new LinkEvent(LINK_REMOVED, link);
+ }
+ return null;
}
}
diff --git a/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleLinkManagerTest.java b/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleLinkManagerTest.java
index d8465ef..8dd9e1d 100644
--- a/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleLinkManagerTest.java
+++ b/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleLinkManagerTest.java
@@ -1,5 +1,6 @@
package org.onlab.onos.net.trivial.impl;
+import com.google.common.collect.ImmutableSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -12,7 +13,6 @@
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.link.DefaultLinkDescription;
import org.onlab.onos.net.link.LinkAdminService;
-import org.onlab.onos.net.link.LinkDescription;
import org.onlab.onos.net.link.LinkEvent;
import org.onlab.onos.net.link.LinkListener;
import org.onlab.onos.net.link.LinkProvider;
@@ -23,10 +23,15 @@
import org.onlab.onos.net.provider.ProviderId;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import static org.junit.Assert.*;
import static org.onlab.onos.net.DeviceId.deviceId;
+import static org.onlab.onos.net.Link.Type.DIRECT;
+import static org.onlab.onos.net.Link.Type.INDIRECT;
+import static org.onlab.onos.net.link.LinkEvent.Type.*;
/**
* Test codifying the link service & link provider service contracts.
@@ -36,6 +41,7 @@
private static final ProviderId PID = new ProviderId("foo");
private static final DeviceId DID1 = deviceId("of:foo");
private static final DeviceId DID2 = deviceId("of:bar");
+ private static final DeviceId DID3 = deviceId("of:goo");
private static final PortNumber P1 = PortNumber.portNumber(1);
private static final PortNumber P2 = PortNumber.portNumber(2);
@@ -77,13 +83,146 @@
mgr.deactivate();
}
-
@Test
public void createLink() {
- LinkDescription ld = new DefaultLinkDescription(new ConnectPoint(DID1, P1),
- new ConnectPoint(DID2, P2),
- Link.Type.DIRECT);
- providerService.linkDetected(ld);
+ addLink(DID1, P1, DID2, P2, DIRECT);
+ addLink(DID2, P2, DID1, P1, DIRECT);
+ assertEquals("incorrect link count", 2, service.getLinkCount());
+
+ Iterator<Link> it = service.getLinks().iterator();
+ it.next();
+ it.next();
+ assertFalse("incorrect link count", it.hasNext());
+ }
+
+ @Test
+ public void updateLink() {
+ addLink(DID1, P1, DID2, P2, DIRECT);
+ addLink(DID2, P2, DID1, P1, INDIRECT);
+ assertEquals("incorrect link count", 2, service.getLinkCount());
+
+ providerService.linkDetected(new DefaultLinkDescription(cp(DID2, P2), cp(DID1, P1), DIRECT));
+ validateEvents(LINK_UPDATED);
+ assertEquals("incorrect link count", 2, service.getLinkCount());
+
+ providerService.linkDetected(new DefaultLinkDescription(cp(DID2, P2), cp(DID1, P1), INDIRECT));
+ providerService.linkDetected(new DefaultLinkDescription(cp(DID2, P2), cp(DID1, P1), DIRECT));
+ assertEquals("no events expected", 0, listener.events.size());
+ }
+
+ @Test
+ public void removeLink() {
+ addLink(DID1, P1, DID2, P2, DIRECT);
+ addLink(DID2, P2, DID1, P1, DIRECT);
+ assertEquals("incorrect link count", 2, service.getLinkCount());
+
+ providerService.linkVanished(new DefaultLinkDescription(cp(DID1, P1), cp(DID2, P2), DIRECT));
+ validateEvents(LINK_REMOVED);
+ assertEquals("incorrect link count", 1, service.getLinkCount());
+ assertNull("link should not be found", service.getLink(cp(DID1, P1), cp(DID2, P2)));
+ assertNotNull("link should be found", service.getLink(cp(DID2, P2), cp(DID1, P1)));
+
+ providerService.linkVanished(new DefaultLinkDescription(cp(DID1, P1), cp(DID2, P2), DIRECT));
+ assertEquals("no events expected", 0, listener.events.size());
+ }
+
+ @Test
+ public void removeLinksByConnectionPoint() {
+ Link l1 = addLink(DID1, P1, DID2, P2, DIRECT);
+ Link l2 = addLink(DID2, P2, DID1, P1, DIRECT);
+ addLink(DID3, P3, DID2, P1, DIRECT);
+ addLink(DID2, P1, DID3, P3, DIRECT);
+ assertEquals("incorrect link count", 4, service.getLinkCount());
+
+ providerService.linksVanished(cp(DID1, P1));
+ assertEquals("incorrect link count", 2, service.getLinkCount());
+ assertNull("link should be gone", service.getLink(l1.src(), l1.dst()));
+ assertNull("link should be gone", service.getLink(l2.src(), l2.dst()));
+ }
+
+ @Test
+ public void removeLinksByDevice() {
+ addLink(DID1, P1, DID2, P2, DIRECT);
+ addLink(DID2, P2, DID1, P1, DIRECT);
+ addLink(DID3, P3, DID2, P1, DIRECT);
+ addLink(DID2, P1, DID3, P3, DIRECT);
+ Link l5 = addLink(DID3, P1, DID1, P2, DIRECT);
+ Link l6 = addLink(DID1, P2, DID3, P1, DIRECT);
+ assertEquals("incorrect link count", 6, service.getLinkCount());
+
+ providerService.linksVanished(DID2);
+ assertEquals("incorrect link count", 2, service.getLinkCount());
+ assertNotNull("link should not be gone", service.getLink(l5.src(), l5.dst()));
+ assertNotNull("link should not be gone", service.getLink(l6.src(), l6.dst()));
+ }
+
+ @Test
+ public void removeLinksAsAdminByConnectionPoint() {
+ Link l1 = addLink(DID1, P1, DID2, P2, DIRECT);
+ Link l2 = addLink(DID2, P2, DID1, P1, DIRECT);
+ addLink(DID3, P3, DID2, P1, DIRECT);
+ addLink(DID2, P1, DID3, P3, DIRECT);
+ assertEquals("incorrect link count", 4, service.getLinkCount());
+
+ admin.removeLinks(cp(DID1, P1));
+ assertEquals("incorrect link count", 2, service.getLinkCount());
+ assertNull("link should be gone", service.getLink(l1.src(), l1.dst()));
+ assertNull("link should be gone", service.getLink(l2.src(), l2.dst()));
+ }
+
+ @Test
+ public void removeLinksAsAdminByDevice() {
+ addLink(DID1, P1, DID2, P2, DIRECT);
+ addLink(DID2, P2, DID1, P1, DIRECT);
+ addLink(DID3, P3, DID2, P1, DIRECT);
+ addLink(DID2, P1, DID3, P3, DIRECT);
+ Link l5 = addLink(DID3, P1, DID1, P2, DIRECT);
+ Link l6 = addLink(DID1, P2, DID3, P1, DIRECT);
+ assertEquals("incorrect link count", 6, service.getLinkCount());
+
+ admin.removeLinks(DID2);
+ assertEquals("incorrect link count", 2, service.getLinkCount());
+ assertNotNull("link should not be gone", service.getLink(l5.src(), l5.dst()));
+ assertNotNull("link should not be gone", service.getLink(l6.src(), l6.dst()));
+ }
+
+ @Test
+ public void getLinks() {
+ Link l1 = addLink(DID1, P1, DID2, P2, DIRECT);
+ Link l2 = addLink(DID2, P2, DID1, P1, DIRECT);
+ Link l3 = addLink(DID3, P3, DID2, P1, DIRECT);
+ Link l4 = addLink(DID2, P1, DID3, P3, DIRECT);
+ assertEquals("incorrect link count", 4, service.getLinkCount());
+
+ Set<Link> links = service.getLinks(cp(DID1, P1));
+ assertEquals("incorrect links", ImmutableSet.of(l1, l2), links);
+ links = service.getEgressLinks(cp(DID1, P1));
+ assertEquals("incorrect links", ImmutableSet.of(l1), links);
+ links = service.getIngressLinks(cp(DID1, P1));
+ assertEquals("incorrect links", ImmutableSet.of(l2), links);
+
+ links = service.getDeviceLinks(DID2);
+ assertEquals("incorrect links", ImmutableSet.of(l1, l2, l3, l4), links);
+ links = service.getDeviceLinks(DID3);
+ assertEquals("incorrect links", ImmutableSet.of(l3, l4), links);
+
+ links = service.getDeviceEgressLinks(DID2);
+ assertEquals("incorrect links", ImmutableSet.of(l2, l4), links);
+ links = service.getDeviceIngressLinks(DID2);
+ assertEquals("incorrect links", ImmutableSet.of(l1, l3), links);
+ }
+
+
+ private Link addLink(DeviceId sd, PortNumber sp, DeviceId dd, PortNumber dp,
+ Link.Type type) {
+ providerService.linkDetected(new DefaultLinkDescription(cp(sd, sp), cp(dd, dp), type));
+ Link link = listener.events.get(0).subject();
+ validateEvents(LINK_ADDED);
+ return link;
+ }
+
+ private ConnectPoint cp(DeviceId id, PortNumber portNumber) {
+ return new ConnectPoint(id, portNumber);
}
protected void validateEvents(Enum... types) {