tom

Finished unit tests for trivial link manager.

...@@ -37,7 +37,7 @@ public class DefaultLinkDescription implements LinkDescription { ...@@ -37,7 +37,7 @@ public class DefaultLinkDescription implements LinkDescription {
37 37
38 @Override 38 @Override
39 public Link.Type type() { 39 public Link.Type type() {
40 - return null; 40 + return type;
41 } 41 }
42 42
43 } 43 }
......
...@@ -18,6 +18,11 @@ public class LinkEvent extends AbstractEvent<LinkEvent.Type, Link> { ...@@ -18,6 +18,11 @@ public class LinkEvent extends AbstractEvent<LinkEvent.Type, Link> {
18 LINK_ADDED, 18 LINK_ADDED,
19 19
20 /** 20 /**
21 + * Signifies that a link has been updated.
22 + */
23 + LINK_UPDATED,
24 +
25 + /**
21 * Signifies that a link has been removed. 26 * Signifies that a link has been removed.
22 */ 27 */
23 LINK_REMOVED 28 LINK_REMOVED
......
...@@ -48,7 +48,7 @@ public interface LinkService { ...@@ -48,7 +48,7 @@ public interface LinkService {
48 * @param deviceId device identifier 48 * @param deviceId device identifier
49 * @return set of device ingress links 49 * @return set of device ingress links
50 */ 50 */
51 - Set<Link> getDeviceInressLinks(DeviceId deviceId); 51 + Set<Link> getDeviceIngressLinks(DeviceId deviceId);
52 52
53 /** 53 /**
54 * Returns set of all infrastructure links leading to and from the 54 * Returns set of all infrastructure links leading to and from the
...@@ -75,17 +75,17 @@ public interface LinkService { ...@@ -75,17 +75,17 @@ public interface LinkService {
75 * @param connectPoint connection point 75 * @param connectPoint connection point
76 * @return set of device ingress links 76 * @return set of device ingress links
77 */ 77 */
78 - Set<Link> getInressLinks(ConnectPoint connectPoint); 78 + Set<Link> getIngressLinks(ConnectPoint connectPoint);
79 79
80 /** 80 /**
81 - * Returns set of all infrastructure links between the specified source 81 + * Returns the infrastructure links between the specified source
82 * and destination connection points. 82 * and destination connection points.
83 * 83 *
84 * @param src source connection point 84 * @param src source connection point
85 * @param dst destination connection point 85 * @param dst destination connection point
86 - * @return set of links 86 + * @return link from source to destination; null if none found
87 */ 87 */
88 - Set<Link> getLinks(ConnectPoint src, ConnectPoint dst); 88 + Link getLink(ConnectPoint src, ConnectPoint dst);
89 89
90 /** 90 /**
91 * Adds the specified link listener. 91 * Adds the specified link listener.
......
...@@ -93,7 +93,7 @@ public class SimpleLinkManager ...@@ -93,7 +93,7 @@ public class SimpleLinkManager
93 } 93 }
94 94
95 @Override 95 @Override
96 - public Set<Link> getDeviceInressLinks(DeviceId deviceId) { 96 + public Set<Link> getDeviceIngressLinks(DeviceId deviceId) {
97 checkNotNull(deviceId, DEVICE_ID_NULL); 97 checkNotNull(deviceId, DEVICE_ID_NULL);
98 return store.getDeviceIngressLinks(deviceId); 98 return store.getDeviceIngressLinks(deviceId);
99 } 99 }
...@@ -112,17 +112,16 @@ public class SimpleLinkManager ...@@ -112,17 +112,16 @@ public class SimpleLinkManager
112 } 112 }
113 113
114 @Override 114 @Override
115 - public Set<Link> getInressLinks(ConnectPoint connectPoint) { 115 + public Set<Link> getIngressLinks(ConnectPoint connectPoint) {
116 checkNotNull(connectPoint, CONNECT_POINT_NULL); 116 checkNotNull(connectPoint, CONNECT_POINT_NULL);
117 return store.getIngressLinks(connectPoint); 117 return store.getIngressLinks(connectPoint);
118 } 118 }
119 119
120 @Override 120 @Override
121 - public Set<Link> getLinks(ConnectPoint src, ConnectPoint dst) { 121 + public Link getLink(ConnectPoint src, ConnectPoint dst) {
122 checkNotNull(src, CONNECT_POINT_NULL); 122 checkNotNull(src, CONNECT_POINT_NULL);
123 checkNotNull(dst, CONNECT_POINT_NULL); 123 checkNotNull(dst, CONNECT_POINT_NULL);
124 - return Sets.intersection(store.getEgressLinks(src), 124 + return store.getLink(src, dst);
125 - store.getIngressLinks(dst));
126 } 125 }
127 126
128 @Override 127 @Override
......
...@@ -18,6 +18,12 @@ import java.util.Objects; ...@@ -18,6 +18,12 @@ import java.util.Objects;
18 import java.util.Set; 18 import java.util.Set;
19 import java.util.concurrent.ConcurrentHashMap; 19 import java.util.concurrent.ConcurrentHashMap;
20 20
21 +import static org.onlab.onos.net.Link.Type.DIRECT;
22 +import static org.onlab.onos.net.Link.Type.INDIRECT;
23 +import static org.onlab.onos.net.link.LinkEvent.Type.LINK_ADDED;
24 +import static org.onlab.onos.net.link.LinkEvent.Type.LINK_REMOVED;
25 +import static org.onlab.onos.net.link.LinkEvent.Type.LINK_UPDATED;
26 +
21 /** 27 /**
22 * Manages inventory of infrastructure links using trivial in-memory link 28 * Manages inventory of infrastructure links using trivial in-memory link
23 * implementation. 29 * implementation.
...@@ -72,6 +78,17 @@ class SimpleLinkStore { ...@@ -72,6 +78,17 @@ class SimpleLinkStore {
72 } 78 }
73 79
74 /** 80 /**
81 + * Returns the link between the two end-points.
82 + *
83 + * @param src source connection point
84 + * @param dst destination connection point
85 + * @return link or null if one not found between the end-points
86 + */
87 + Link getLink(ConnectPoint src, ConnectPoint dst) {
88 + return links.get(new LinkKey(src, dst));
89 + }
90 +
91 + /**
75 * Returns all links egressing from the specified connection point. 92 * Returns all links egressing from the specified connection point.
76 * 93 *
77 * @param src source connection point 94 * @param src source connection point
...@@ -96,14 +113,13 @@ class SimpleLinkStore { ...@@ -96,14 +113,13 @@ class SimpleLinkStore {
96 Set<Link> getIngressLinks(ConnectPoint dst) { 113 Set<Link> getIngressLinks(ConnectPoint dst) {
97 Set<Link> ingress = new HashSet<>(); 114 Set<Link> ingress = new HashSet<>();
98 for (Link link : dstLinks.get(dst.deviceId())) { 115 for (Link link : dstLinks.get(dst.deviceId())) {
99 - if (link.src().equals(dst)) { 116 + if (link.dst().equals(dst)) {
100 ingress.add(link); 117 ingress.add(link);
101 } 118 }
102 } 119 }
103 return ingress; 120 return ingress;
104 } 121 }
105 122
106 -
107 /** 123 /**
108 * Creates a new link, or updates an existing one, based on the given 124 * Creates a new link, or updates an existing one, based on the given
109 * information. 125 * information.
...@@ -119,7 +135,7 @@ class SimpleLinkStore { ...@@ -119,7 +135,7 @@ class SimpleLinkStore {
119 if (link == null) { 135 if (link == null) {
120 return createLink(providerId, key, linkDescription); 136 return createLink(providerId, key, linkDescription);
121 } 137 }
122 - return updateLink(link, linkDescription); 138 + return updateLink(providerId, link, key, linkDescription);
123 } 139 }
124 140
125 // Creates and stores the link and returns the appropriate event. 141 // Creates and stores the link and returns the appropriate event.
...@@ -132,11 +148,26 @@ class SimpleLinkStore { ...@@ -132,11 +148,26 @@ class SimpleLinkStore {
132 srcLinks.put(link.src().deviceId(), link); 148 srcLinks.put(link.src().deviceId(), link);
133 dstLinks.put(link.dst().deviceId(), link); 149 dstLinks.put(link.dst().deviceId(), link);
134 } 150 }
135 - return new LinkEvent(LinkEvent.Type.LINK_ADDED, link); 151 + return new LinkEvent(LINK_ADDED, link);
136 } 152 }
137 153
138 // Updates, if necessary the specified link and returns the appropriate event. 154 // Updates, if necessary the specified link and returns the appropriate event.
139 - private LinkEvent updateLink(DefaultLink link, LinkDescription linkDescription) { 155 + private LinkEvent updateLink(ProviderId providerId, DefaultLink link,
156 + LinkKey key, LinkDescription linkDescription) {
157 + if (link.type() == INDIRECT && linkDescription.type() == DIRECT) {
158 + synchronized (this) {
159 + srcLinks.remove(link.src().deviceId(), link);
160 + dstLinks.remove(link.dst().deviceId(), link);
161 +
162 + DefaultLink updated =
163 + new DefaultLink(providerId, link.src(), link.dst(),
164 + linkDescription.type());
165 + links.put(key, updated);
166 + srcLinks.put(link.src().deviceId(), updated);
167 + dstLinks.put(link.dst().deviceId(), updated);
168 + return new LinkEvent(LINK_UPDATED, updated);
169 + }
170 + }
140 return null; 171 return null;
141 } 172 }
142 173
...@@ -150,9 +181,12 @@ class SimpleLinkStore { ...@@ -150,9 +181,12 @@ class SimpleLinkStore {
150 LinkEvent removeLink(ConnectPoint src, ConnectPoint dst) { 181 LinkEvent removeLink(ConnectPoint src, ConnectPoint dst) {
151 synchronized (this) { 182 synchronized (this) {
152 Link link = links.remove(new LinkKey(src, dst)); 183 Link link = links.remove(new LinkKey(src, dst));
153 - srcLinks.remove(link.src().deviceId(), link); 184 + if (link != null) {
154 - dstLinks.remove(link.dst().deviceId(), link); 185 + srcLinks.remove(link.src().deviceId(), link);
155 - return link == null ? null : new LinkEvent(LinkEvent.Type.LINK_REMOVED, link); 186 + dstLinks.remove(link.dst().deviceId(), link);
187 + return new LinkEvent(LINK_REMOVED, link);
188 + }
189 + return null;
156 } 190 }
157 } 191 }
158 192
......
1 package org.onlab.onos.net.trivial.impl; 1 package org.onlab.onos.net.trivial.impl;
2 2
3 +import com.google.common.collect.ImmutableSet;
3 import org.junit.After; 4 import org.junit.After;
4 import org.junit.Before; 5 import org.junit.Before;
5 import org.junit.Test; 6 import org.junit.Test;
...@@ -12,7 +13,6 @@ import org.onlab.onos.net.MastershipRole; ...@@ -12,7 +13,6 @@ import org.onlab.onos.net.MastershipRole;
12 import org.onlab.onos.net.PortNumber; 13 import org.onlab.onos.net.PortNumber;
13 import org.onlab.onos.net.link.DefaultLinkDescription; 14 import org.onlab.onos.net.link.DefaultLinkDescription;
14 import org.onlab.onos.net.link.LinkAdminService; 15 import org.onlab.onos.net.link.LinkAdminService;
15 -import org.onlab.onos.net.link.LinkDescription;
16 import org.onlab.onos.net.link.LinkEvent; 16 import org.onlab.onos.net.link.LinkEvent;
17 import org.onlab.onos.net.link.LinkListener; 17 import org.onlab.onos.net.link.LinkListener;
18 import org.onlab.onos.net.link.LinkProvider; 18 import org.onlab.onos.net.link.LinkProvider;
...@@ -23,10 +23,15 @@ import org.onlab.onos.net.provider.AbstractProvider; ...@@ -23,10 +23,15 @@ import org.onlab.onos.net.provider.AbstractProvider;
23 import org.onlab.onos.net.provider.ProviderId; 23 import org.onlab.onos.net.provider.ProviderId;
24 24
25 import java.util.ArrayList; 25 import java.util.ArrayList;
26 +import java.util.Iterator;
26 import java.util.List; 27 import java.util.List;
28 +import java.util.Set;
27 29
28 import static org.junit.Assert.*; 30 import static org.junit.Assert.*;
29 import static org.onlab.onos.net.DeviceId.deviceId; 31 import static org.onlab.onos.net.DeviceId.deviceId;
32 +import static org.onlab.onos.net.Link.Type.DIRECT;
33 +import static org.onlab.onos.net.Link.Type.INDIRECT;
34 +import static org.onlab.onos.net.link.LinkEvent.Type.*;
30 35
31 /** 36 /**
32 * Test codifying the link service & link provider service contracts. 37 * Test codifying the link service & link provider service contracts.
...@@ -36,6 +41,7 @@ public class SimpleLinkManagerTest { ...@@ -36,6 +41,7 @@ public class SimpleLinkManagerTest {
36 private static final ProviderId PID = new ProviderId("foo"); 41 private static final ProviderId PID = new ProviderId("foo");
37 private static final DeviceId DID1 = deviceId("of:foo"); 42 private static final DeviceId DID1 = deviceId("of:foo");
38 private static final DeviceId DID2 = deviceId("of:bar"); 43 private static final DeviceId DID2 = deviceId("of:bar");
44 + private static final DeviceId DID3 = deviceId("of:goo");
39 45
40 private static final PortNumber P1 = PortNumber.portNumber(1); 46 private static final PortNumber P1 = PortNumber.portNumber(1);
41 private static final PortNumber P2 = PortNumber.portNumber(2); 47 private static final PortNumber P2 = PortNumber.portNumber(2);
...@@ -77,13 +83,146 @@ public class SimpleLinkManagerTest { ...@@ -77,13 +83,146 @@ public class SimpleLinkManagerTest {
77 mgr.deactivate(); 83 mgr.deactivate();
78 } 84 }
79 85
80 -
81 @Test 86 @Test
82 public void createLink() { 87 public void createLink() {
83 - LinkDescription ld = new DefaultLinkDescription(new ConnectPoint(DID1, P1), 88 + addLink(DID1, P1, DID2, P2, DIRECT);
84 - new ConnectPoint(DID2, P2), 89 + addLink(DID2, P2, DID1, P1, DIRECT);
85 - Link.Type.DIRECT); 90 + assertEquals("incorrect link count", 2, service.getLinkCount());
86 - providerService.linkDetected(ld); 91 +
92 + Iterator<Link> it = service.getLinks().iterator();
93 + it.next();
94 + it.next();
95 + assertFalse("incorrect link count", it.hasNext());
96 + }
97 +
98 + @Test
99 + public void updateLink() {
100 + addLink(DID1, P1, DID2, P2, DIRECT);
101 + addLink(DID2, P2, DID1, P1, INDIRECT);
102 + assertEquals("incorrect link count", 2, service.getLinkCount());
103 +
104 + providerService.linkDetected(new DefaultLinkDescription(cp(DID2, P2), cp(DID1, P1), DIRECT));
105 + validateEvents(LINK_UPDATED);
106 + assertEquals("incorrect link count", 2, service.getLinkCount());
107 +
108 + providerService.linkDetected(new DefaultLinkDescription(cp(DID2, P2), cp(DID1, P1), INDIRECT));
109 + providerService.linkDetected(new DefaultLinkDescription(cp(DID2, P2), cp(DID1, P1), DIRECT));
110 + assertEquals("no events expected", 0, listener.events.size());
111 + }
112 +
113 + @Test
114 + public void removeLink() {
115 + addLink(DID1, P1, DID2, P2, DIRECT);
116 + addLink(DID2, P2, DID1, P1, DIRECT);
117 + assertEquals("incorrect link count", 2, service.getLinkCount());
118 +
119 + providerService.linkVanished(new DefaultLinkDescription(cp(DID1, P1), cp(DID2, P2), DIRECT));
120 + validateEvents(LINK_REMOVED);
121 + assertEquals("incorrect link count", 1, service.getLinkCount());
122 + assertNull("link should not be found", service.getLink(cp(DID1, P1), cp(DID2, P2)));
123 + assertNotNull("link should be found", service.getLink(cp(DID2, P2), cp(DID1, P1)));
124 +
125 + providerService.linkVanished(new DefaultLinkDescription(cp(DID1, P1), cp(DID2, P2), DIRECT));
126 + assertEquals("no events expected", 0, listener.events.size());
127 + }
128 +
129 + @Test
130 + public void removeLinksByConnectionPoint() {
131 + Link l1 = addLink(DID1, P1, DID2, P2, DIRECT);
132 + Link l2 = addLink(DID2, P2, DID1, P1, DIRECT);
133 + addLink(DID3, P3, DID2, P1, DIRECT);
134 + addLink(DID2, P1, DID3, P3, DIRECT);
135 + assertEquals("incorrect link count", 4, service.getLinkCount());
136 +
137 + providerService.linksVanished(cp(DID1, P1));
138 + assertEquals("incorrect link count", 2, service.getLinkCount());
139 + assertNull("link should be gone", service.getLink(l1.src(), l1.dst()));
140 + assertNull("link should be gone", service.getLink(l2.src(), l2.dst()));
141 + }
142 +
143 + @Test
144 + public void removeLinksByDevice() {
145 + addLink(DID1, P1, DID2, P2, DIRECT);
146 + addLink(DID2, P2, DID1, P1, DIRECT);
147 + addLink(DID3, P3, DID2, P1, DIRECT);
148 + addLink(DID2, P1, DID3, P3, DIRECT);
149 + Link l5 = addLink(DID3, P1, DID1, P2, DIRECT);
150 + Link l6 = addLink(DID1, P2, DID3, P1, DIRECT);
151 + assertEquals("incorrect link count", 6, service.getLinkCount());
152 +
153 + providerService.linksVanished(DID2);
154 + assertEquals("incorrect link count", 2, service.getLinkCount());
155 + assertNotNull("link should not be gone", service.getLink(l5.src(), l5.dst()));
156 + assertNotNull("link should not be gone", service.getLink(l6.src(), l6.dst()));
157 + }
158 +
159 + @Test
160 + public void removeLinksAsAdminByConnectionPoint() {
161 + Link l1 = addLink(DID1, P1, DID2, P2, DIRECT);
162 + Link l2 = addLink(DID2, P2, DID1, P1, DIRECT);
163 + addLink(DID3, P3, DID2, P1, DIRECT);
164 + addLink(DID2, P1, DID3, P3, DIRECT);
165 + assertEquals("incorrect link count", 4, service.getLinkCount());
166 +
167 + admin.removeLinks(cp(DID1, P1));
168 + assertEquals("incorrect link count", 2, service.getLinkCount());
169 + assertNull("link should be gone", service.getLink(l1.src(), l1.dst()));
170 + assertNull("link should be gone", service.getLink(l2.src(), l2.dst()));
171 + }
172 +
173 + @Test
174 + public void removeLinksAsAdminByDevice() {
175 + addLink(DID1, P1, DID2, P2, DIRECT);
176 + addLink(DID2, P2, DID1, P1, DIRECT);
177 + addLink(DID3, P3, DID2, P1, DIRECT);
178 + addLink(DID2, P1, DID3, P3, DIRECT);
179 + Link l5 = addLink(DID3, P1, DID1, P2, DIRECT);
180 + Link l6 = addLink(DID1, P2, DID3, P1, DIRECT);
181 + assertEquals("incorrect link count", 6, service.getLinkCount());
182 +
183 + admin.removeLinks(DID2);
184 + assertEquals("incorrect link count", 2, service.getLinkCount());
185 + assertNotNull("link should not be gone", service.getLink(l5.src(), l5.dst()));
186 + assertNotNull("link should not be gone", service.getLink(l6.src(), l6.dst()));
187 + }
188 +
189 + @Test
190 + public void getLinks() {
191 + Link l1 = addLink(DID1, P1, DID2, P2, DIRECT);
192 + Link l2 = addLink(DID2, P2, DID1, P1, DIRECT);
193 + Link l3 = addLink(DID3, P3, DID2, P1, DIRECT);
194 + Link l4 = addLink(DID2, P1, DID3, P3, DIRECT);
195 + assertEquals("incorrect link count", 4, service.getLinkCount());
196 +
197 + Set<Link> links = service.getLinks(cp(DID1, P1));
198 + assertEquals("incorrect links", ImmutableSet.of(l1, l2), links);
199 + links = service.getEgressLinks(cp(DID1, P1));
200 + assertEquals("incorrect links", ImmutableSet.of(l1), links);
201 + links = service.getIngressLinks(cp(DID1, P1));
202 + assertEquals("incorrect links", ImmutableSet.of(l2), links);
203 +
204 + links = service.getDeviceLinks(DID2);
205 + assertEquals("incorrect links", ImmutableSet.of(l1, l2, l3, l4), links);
206 + links = service.getDeviceLinks(DID3);
207 + assertEquals("incorrect links", ImmutableSet.of(l3, l4), links);
208 +
209 + links = service.getDeviceEgressLinks(DID2);
210 + assertEquals("incorrect links", ImmutableSet.of(l2, l4), links);
211 + links = service.getDeviceIngressLinks(DID2);
212 + assertEquals("incorrect links", ImmutableSet.of(l1, l3), links);
213 + }
214 +
215 +
216 + private Link addLink(DeviceId sd, PortNumber sp, DeviceId dd, PortNumber dp,
217 + Link.Type type) {
218 + providerService.linkDetected(new DefaultLinkDescription(cp(sd, sp), cp(dd, dp), type));
219 + Link link = listener.events.get(0).subject();
220 + validateEvents(LINK_ADDED);
221 + return link;
222 + }
223 +
224 + private ConnectPoint cp(DeviceId id, PortNumber portNumber) {
225 + return new ConnectPoint(id, portNumber);
87 } 226 }
88 227
89 protected void validateEvents(Enum... types) { 228 protected void validateEvents(Enum... types) {
......