blob: a7f40ac4d9edeb74df082d2e76fc88e7b928779c [file] [log] [blame]
tomea961ff2014-10-01 12:45:15 -07001package org.onlab.onos.store.trivial.impl;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -07002
Thomas Vachuska0e752bd2014-10-22 22:33:41 -07003import com.google.common.collect.Iterables;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -07004import org.junit.After;
5import org.junit.AfterClass;
6import org.junit.Before;
7import org.junit.BeforeClass;
8import org.junit.Ignore;
9import org.junit.Test;
10import org.onlab.onos.net.ConnectPoint;
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070011import org.onlab.onos.net.DefaultAnnotations;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070012import org.onlab.onos.net.DeviceId;
13import org.onlab.onos.net.Link;
Thomas Vachuska0e752bd2014-10-22 22:33:41 -070014import org.onlab.onos.net.Link.Type;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070015import org.onlab.onos.net.LinkKey;
16import org.onlab.onos.net.PortNumber;
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070017import org.onlab.onos.net.SparseAnnotations;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070018import org.onlab.onos.net.link.DefaultLinkDescription;
19import org.onlab.onos.net.link.LinkEvent;
20import org.onlab.onos.net.link.LinkStore;
21import org.onlab.onos.net.link.LinkStoreDelegate;
22import org.onlab.onos.net.provider.ProviderId;
23
Thomas Vachuska0e752bd2014-10-22 22:33:41 -070024import java.util.HashMap;
25import java.util.Map;
26import java.util.Set;
27import java.util.concurrent.CountDownLatch;
28import java.util.concurrent.TimeUnit;
29
30import static org.junit.Assert.*;
31import static org.onlab.onos.net.DeviceId.deviceId;
32import static org.onlab.onos.net.Link.Type.*;
33import static org.onlab.onos.net.link.LinkEvent.Type.*;
34import static org.onlab.onos.store.trivial.impl.SimpleDeviceStoreTest.assertAnnotationsEquals;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070035
36/**
37 * Test of the simple LinkStore implementation.
38 */
39public class SimpleLinkStoreTest {
40
41 private static final ProviderId PID = new ProviderId("of", "foo");
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070042 private static final ProviderId PIDA = new ProviderId("of", "bar", true);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070043 private static final DeviceId DID1 = deviceId("of:foo");
44 private static final DeviceId DID2 = deviceId("of:bar");
45
46 private static final PortNumber P1 = PortNumber.portNumber(1);
47 private static final PortNumber P2 = PortNumber.portNumber(2);
48 private static final PortNumber P3 = PortNumber.portNumber(3);
49
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070050 private static final SparseAnnotations A1 = DefaultAnnotations.builder()
51 .set("A1", "a1")
52 .set("B1", "b1")
53 .build();
54 private static final SparseAnnotations A1_2 = DefaultAnnotations.builder()
55 .remove("A1")
56 .set("B3", "b3")
57 .build();
58 private static final SparseAnnotations A2 = DefaultAnnotations.builder()
59 .set("A2", "a2")
60 .set("B2", "b2")
61 .build();
62 private static final SparseAnnotations A2_2 = DefaultAnnotations.builder()
63 .remove("A2")
64 .set("B4", "b4")
65 .build();
66
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070067
68 private SimpleLinkStore simpleLinkStore;
69 private LinkStore linkStore;
70
71 @BeforeClass
72 public static void setUpBeforeClass() throws Exception {
73 }
74
75 @AfterClass
76 public static void tearDownAfterClass() throws Exception {
77 }
78
79 @Before
80 public void setUp() throws Exception {
81 simpleLinkStore = new SimpleLinkStore();
82 simpleLinkStore.activate();
83 linkStore = simpleLinkStore;
84 }
85
86 @After
87 public void tearDown() throws Exception {
88 simpleLinkStore.deactivate();
89 }
90
91 private void putLink(DeviceId srcId, PortNumber srcNum,
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -070092 DeviceId dstId, PortNumber dstNum, Type type,
93 SparseAnnotations... annotations) {
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070094 ConnectPoint src = new ConnectPoint(srcId, srcNum);
95 ConnectPoint dst = new ConnectPoint(dstId, dstNum);
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -070096 linkStore.createOrUpdateLink(PID, new DefaultLinkDescription(src, dst, type, annotations));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070097 }
98
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -070099 private void putLink(LinkKey key, Type type, SparseAnnotations... annotations) {
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700100 putLink(key.src().deviceId(), key.src().port(),
101 key.dst().deviceId(), key.dst().port(),
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700102 type, annotations);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700103 }
104
105 private static void assertLink(DeviceId srcId, PortNumber srcNum,
106 DeviceId dstId, PortNumber dstNum, Type type,
107 Link link) {
108 assertEquals(srcId, link.src().deviceId());
109 assertEquals(srcNum, link.src().port());
110 assertEquals(dstId, link.dst().deviceId());
111 assertEquals(dstNum, link.dst().port());
112 assertEquals(type, link.type());
113 }
114
115 private static void assertLink(LinkKey key, Type type, Link link) {
116 assertLink(key.src().deviceId(), key.src().port(),
117 key.dst().deviceId(), key.dst().port(),
118 type, link);
119 }
120
121 @Test
122 public final void testGetLinkCount() {
123 assertEquals("initialy empty", 0, linkStore.getLinkCount());
124
125 putLink(DID1, P1, DID2, P2, DIRECT);
126 putLink(DID2, P2, DID1, P1, DIRECT);
127 putLink(DID1, P1, DID2, P2, DIRECT);
128
129 assertEquals("expecting 2 unique link", 2, linkStore.getLinkCount());
130 }
131
132 @Test
133 public final void testGetLinks() {
134 assertEquals("initialy empty", 0,
135 Iterables.size(linkStore.getLinks()));
136
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700137 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
138 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700139
140 putLink(linkId1, DIRECT);
141 putLink(linkId2, DIRECT);
142 putLink(linkId1, DIRECT);
143
144 assertEquals("expecting 2 unique link", 2,
145 Iterables.size(linkStore.getLinks()));
146
147 Map<LinkKey, Link> links = new HashMap<>();
148 for (Link link : linkStore.getLinks()) {
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700149 links.put(LinkKey.linkKey(link), link);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700150 }
151
152 assertLink(linkId1, DIRECT, links.get(linkId1));
153 assertLink(linkId2, DIRECT, links.get(linkId2));
154 }
155
156 @Test
157 public final void testGetDeviceEgressLinks() {
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700158 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
159 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
160 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700161
162 putLink(linkId1, DIRECT);
163 putLink(linkId2, DIRECT);
164 putLink(linkId3, DIRECT);
165
166 // DID1,P1 => DID2,P2
167 // DID2,P2 => DID1,P1
168 // DID1,P2 => DID2,P3
169
170 Set<Link> links1 = linkStore.getDeviceEgressLinks(DID1);
171 assertEquals(2, links1.size());
172 // check
173
174 Set<Link> links2 = linkStore.getDeviceEgressLinks(DID2);
175 assertEquals(1, links2.size());
176 assertLink(linkId2, DIRECT, links2.iterator().next());
177 }
178
179 @Test
180 public final void testGetDeviceIngressLinks() {
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700181 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
182 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
183 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700184
185 putLink(linkId1, DIRECT);
186 putLink(linkId2, DIRECT);
187 putLink(linkId3, DIRECT);
188
189 // DID1,P1 => DID2,P2
190 // DID2,P2 => DID1,P1
191 // DID1,P2 => DID2,P3
192
193 Set<Link> links1 = linkStore.getDeviceIngressLinks(DID2);
194 assertEquals(2, links1.size());
195 // check
196
197 Set<Link> links2 = linkStore.getDeviceIngressLinks(DID1);
198 assertEquals(1, links2.size());
199 assertLink(linkId2, DIRECT, links2.iterator().next());
200 }
201
202 @Test
203 public final void testGetLink() {
204 ConnectPoint src = new ConnectPoint(DID1, P1);
205 ConnectPoint dst = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700206 LinkKey linkId1 = LinkKey.linkKey(src, dst);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700207
208 putLink(linkId1, DIRECT);
209
210 Link link = linkStore.getLink(src, dst);
211 assertLink(linkId1, DIRECT, link);
212
213 assertNull("There shouldn't be reverese link",
214 linkStore.getLink(dst, src));
215 }
216
217 @Test
218 public final void testGetEgressLinks() {
219 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
220 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700221 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
222 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
223 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700224
225 putLink(linkId1, DIRECT);
226 putLink(linkId2, DIRECT);
227 putLink(linkId3, DIRECT);
228
229 // DID1,P1 => DID2,P2
230 // DID2,P2 => DID1,P1
231 // DID1,P2 => DID2,P3
232
233 Set<Link> links1 = linkStore.getEgressLinks(d1P1);
234 assertEquals(1, links1.size());
235 assertLink(linkId1, DIRECT, links1.iterator().next());
236
237 Set<Link> links2 = linkStore.getEgressLinks(d2P2);
238 assertEquals(1, links2.size());
239 assertLink(linkId2, DIRECT, links2.iterator().next());
240 }
241
242 @Test
243 public final void testGetIngressLinks() {
244 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
245 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700246 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
247 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
248 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700249
250 putLink(linkId1, DIRECT);
251 putLink(linkId2, DIRECT);
252 putLink(linkId3, DIRECT);
253
254 // DID1,P1 => DID2,P2
255 // DID2,P2 => DID1,P1
256 // DID1,P2 => DID2,P3
257
258 Set<Link> links1 = linkStore.getIngressLinks(d2P2);
259 assertEquals(1, links1.size());
260 assertLink(linkId1, DIRECT, links1.iterator().next());
261
262 Set<Link> links2 = linkStore.getIngressLinks(d1P1);
263 assertEquals(1, links2.size());
264 assertLink(linkId2, DIRECT, links2.iterator().next());
265 }
266
267 @Test
268 public final void testCreateOrUpdateLink() {
269 ConnectPoint src = new ConnectPoint(DID1, P1);
270 ConnectPoint dst = new ConnectPoint(DID2, P2);
271
272 // add link
273 LinkEvent event = linkStore.createOrUpdateLink(PID,
274 new DefaultLinkDescription(src, dst, INDIRECT));
275
276 assertLink(DID1, P1, DID2, P2, INDIRECT, event.subject());
277 assertEquals(LINK_ADDED, event.type());
278
279 // update link type
280 LinkEvent event2 = linkStore.createOrUpdateLink(PID,
281 new DefaultLinkDescription(src, dst, DIRECT));
282
283 assertLink(DID1, P1, DID2, P2, DIRECT, event2.subject());
284 assertEquals(LINK_UPDATED, event2.type());
285
286 // no change
287 LinkEvent event3 = linkStore.createOrUpdateLink(PID,
288 new DefaultLinkDescription(src, dst, DIRECT));
289
290 assertNull("No change event expected", event3);
291 }
292
293 @Test
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700294 public final void testCreateOrUpdateLinkAncillary() {
295 ConnectPoint src = new ConnectPoint(DID1, P1);
296 ConnectPoint dst = new ConnectPoint(DID2, P2);
297
298 // add Ancillary link
299 LinkEvent event = linkStore.createOrUpdateLink(PIDA,
300 new DefaultLinkDescription(src, dst, INDIRECT, A1));
301
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700302 assertNotNull("Ancillary only link is ignored", event);
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700303
304 // add Primary link
305 LinkEvent event2 = linkStore.createOrUpdateLink(PID,
306 new DefaultLinkDescription(src, dst, INDIRECT, A2));
307
308 assertLink(DID1, P1, DID2, P2, INDIRECT, event2.subject());
309 assertAnnotationsEquals(event2.subject().annotations(), A2, A1);
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700310 assertEquals(LINK_UPDATED, event2.type());
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700311
312 // update link type
313 LinkEvent event3 = linkStore.createOrUpdateLink(PID,
314 new DefaultLinkDescription(src, dst, DIRECT, A2));
315 assertLink(DID1, P1, DID2, P2, DIRECT, event3.subject());
316 assertAnnotationsEquals(event3.subject().annotations(), A2, A1);
317 assertEquals(LINK_UPDATED, event3.type());
318
319
320 // no change
321 LinkEvent event4 = linkStore.createOrUpdateLink(PID,
322 new DefaultLinkDescription(src, dst, DIRECT));
323 assertNull("No change event expected", event4);
324
325 // update link annotation (Primary)
326 LinkEvent event5 = linkStore.createOrUpdateLink(PID,
327 new DefaultLinkDescription(src, dst, DIRECT, A2_2));
328 assertLink(DID1, P1, DID2, P2, DIRECT, event5.subject());
329 assertAnnotationsEquals(event5.subject().annotations(), A2, A2_2, A1);
330 assertEquals(LINK_UPDATED, event5.type());
331
332 // update link annotation (Ancillary)
333 LinkEvent event6 = linkStore.createOrUpdateLink(PIDA,
334 new DefaultLinkDescription(src, dst, DIRECT, A1_2));
335 assertLink(DID1, P1, DID2, P2, DIRECT, event6.subject());
336 assertAnnotationsEquals(event6.subject().annotations(), A2, A2_2, A1, A1_2);
337 assertEquals(LINK_UPDATED, event6.type());
338
339 // update link type (Ancillary) : ignored
340 LinkEvent event7 = linkStore.createOrUpdateLink(PIDA,
341 new DefaultLinkDescription(src, dst, EDGE));
342 assertNull("Ancillary change other than annotation is ignored", event7);
343 }
344
345
346 @Test
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700347 public final void testRemoveLink() {
348 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
349 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700350 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
351 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700352
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700353 putLink(linkId1, DIRECT, A1);
354 putLink(linkId2, DIRECT, A2);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700355
356 // DID1,P1 => DID2,P2
357 // DID2,P2 => DID1,P1
358 // DID1,P2 => DID2,P3
359
360 LinkEvent event = linkStore.removeLink(d1P1, d2P2);
361 assertEquals(LINK_REMOVED, event.type());
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700362 assertAnnotationsEquals(event.subject().annotations(), A1);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700363 LinkEvent event2 = linkStore.removeLink(d1P1, d2P2);
364 assertNull(event2);
365
366 assertLink(linkId2, DIRECT, linkStore.getLink(d2P2, d1P1));
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700367 assertAnnotationsEquals(linkStore.getLink(d2P2, d1P1).annotations(), A2);
368
369 // annotations, etc. should not survive remove
370 putLink(linkId1, DIRECT);
371 assertLink(linkId1, DIRECT, linkStore.getLink(d1P1, d2P2));
372 assertAnnotationsEquals(linkStore.getLink(d1P1, d2P2).annotations());
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700373 }
374
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700375 @Test
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700376 public final void testAncillaryVisible() {
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700377 ConnectPoint src = new ConnectPoint(DID1, P1);
378 ConnectPoint dst = new ConnectPoint(DID2, P2);
379
380 // add Ancillary link
381 linkStore.createOrUpdateLink(PIDA,
382 new DefaultLinkDescription(src, dst, INDIRECT, A1));
383
384 // Ancillary only link should not be visible
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700385 assertEquals(1, linkStore.getLinkCount());
386 assertNotNull(linkStore.getLink(src, dst));
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700387 }
388
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700389 // If Delegates should be called only on remote events,
390 // then Simple* should never call them, thus not test required.
391 @Ignore("Ignore until Delegate spec. is clear.")
392 @Test
393 public final void testEvents() throws InterruptedException {
394
395 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
396 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700397 final LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700398
399 final CountDownLatch addLatch = new CountDownLatch(1);
400 LinkStoreDelegate checkAdd = new LinkStoreDelegate() {
401 @Override
402 public void notify(LinkEvent event) {
403 assertEquals(LINK_ADDED, event.type());
404 assertLink(linkId1, INDIRECT, event.subject());
405 addLatch.countDown();
406 }
407 };
408 final CountDownLatch updateLatch = new CountDownLatch(1);
409 LinkStoreDelegate checkUpdate = new LinkStoreDelegate() {
410 @Override
411 public void notify(LinkEvent event) {
412 assertEquals(LINK_UPDATED, event.type());
413 assertLink(linkId1, DIRECT, event.subject());
414 updateLatch.countDown();
415 }
416 };
417 final CountDownLatch removeLatch = new CountDownLatch(1);
418 LinkStoreDelegate checkRemove = new LinkStoreDelegate() {
419 @Override
420 public void notify(LinkEvent event) {
421 assertEquals(LINK_REMOVED, event.type());
422 assertLink(linkId1, DIRECT, event.subject());
423 removeLatch.countDown();
424 }
425 };
426
427 linkStore.setDelegate(checkAdd);
428 putLink(linkId1, INDIRECT);
429 assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
430
431 linkStore.unsetDelegate(checkAdd);
432 linkStore.setDelegate(checkUpdate);
433 putLink(linkId1, DIRECT);
434 assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS));
435
436 linkStore.unsetDelegate(checkUpdate);
437 linkStore.setDelegate(checkRemove);
438 linkStore.removeLink(d1P1, d2P2);
439 assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS));
440 }
441}