tom

Finished unit tests for trivial link manager.

......@@ -37,7 +37,7 @@ public class DefaultLinkDescription implements LinkDescription {
@Override
public Link.Type type() {
return null;
return type;
}
}
......
......@@ -18,6 +18,11 @@ public class LinkEvent extends AbstractEvent<LinkEvent.Type, Link> {
LINK_ADDED,
/**
* Signifies that a link has been updated.
*/
LINK_UPDATED,
/**
* Signifies that a link has been removed.
*/
LINK_REMOVED
......
......@@ -48,7 +48,7 @@ public interface LinkService {
* @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 @@ public interface LinkService {
* @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.
......
......@@ -93,7 +93,7 @@ public class SimpleLinkManager
}
@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 @@ public class SimpleLinkManager
}
@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
......
......@@ -18,6 +18,12 @@ import java.util.Objects;
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 @@ class SimpleLinkStore {
}
/**
* 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 @@ class SimpleLinkStore {
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 @@ class SimpleLinkStore {
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 @@ class SimpleLinkStore {
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 @@ class SimpleLinkStore {
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;
}
}
......
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.MastershipRole;
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.AbstractProvider;
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 @@ public class SimpleLinkManagerTest {
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 @@ public class SimpleLinkManagerTest {
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) {
......