blob: 043cff3954c3204a95a9b49c98cc246d316e62f9 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
tomea961ff2014-10-01 12:45:15 -070016package org.onlab.onos.store.trivial.impl;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070017
Thomas Vachuska0e752bd2014-10-22 22:33:41 -070018import com.google.common.collect.Iterables;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070019import org.junit.After;
20import org.junit.AfterClass;
21import org.junit.Before;
22import org.junit.BeforeClass;
23import org.junit.Ignore;
24import org.junit.Test;
25import org.onlab.onos.net.ConnectPoint;
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070026import org.onlab.onos.net.DefaultAnnotations;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070027import org.onlab.onos.net.DeviceId;
28import org.onlab.onos.net.Link;
Thomas Vachuska0e752bd2014-10-22 22:33:41 -070029import org.onlab.onos.net.Link.Type;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070030import org.onlab.onos.net.LinkKey;
31import org.onlab.onos.net.PortNumber;
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070032import org.onlab.onos.net.SparseAnnotations;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070033import org.onlab.onos.net.link.DefaultLinkDescription;
34import org.onlab.onos.net.link.LinkEvent;
35import org.onlab.onos.net.link.LinkStore;
36import org.onlab.onos.net.link.LinkStoreDelegate;
37import org.onlab.onos.net.provider.ProviderId;
38
Thomas Vachuska0e752bd2014-10-22 22:33:41 -070039import java.util.HashMap;
40import java.util.Map;
41import java.util.Set;
42import java.util.concurrent.CountDownLatch;
43import java.util.concurrent.TimeUnit;
44
45import static org.junit.Assert.*;
46import static org.onlab.onos.net.DeviceId.deviceId;
47import static org.onlab.onos.net.Link.Type.*;
48import static org.onlab.onos.net.link.LinkEvent.Type.*;
49import static org.onlab.onos.store.trivial.impl.SimpleDeviceStoreTest.assertAnnotationsEquals;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070050
51/**
52 * Test of the simple LinkStore implementation.
53 */
54public class SimpleLinkStoreTest {
55
56 private static final ProviderId PID = new ProviderId("of", "foo");
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070057 private static final ProviderId PIDA = new ProviderId("of", "bar", true);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070058 private static final DeviceId DID1 = deviceId("of:foo");
59 private static final DeviceId DID2 = deviceId("of:bar");
60
61 private static final PortNumber P1 = PortNumber.portNumber(1);
62 private static final PortNumber P2 = PortNumber.portNumber(2);
63 private static final PortNumber P3 = PortNumber.portNumber(3);
64
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070065 private static final SparseAnnotations A1 = DefaultAnnotations.builder()
66 .set("A1", "a1")
67 .set("B1", "b1")
68 .build();
69 private static final SparseAnnotations A1_2 = DefaultAnnotations.builder()
70 .remove("A1")
71 .set("B3", "b3")
72 .build();
73 private static final SparseAnnotations A2 = DefaultAnnotations.builder()
74 .set("A2", "a2")
75 .set("B2", "b2")
76 .build();
77 private static final SparseAnnotations A2_2 = DefaultAnnotations.builder()
78 .remove("A2")
79 .set("B4", "b4")
80 .build();
81
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070082
83 private SimpleLinkStore simpleLinkStore;
84 private LinkStore linkStore;
85
86 @BeforeClass
87 public static void setUpBeforeClass() throws Exception {
88 }
89
90 @AfterClass
91 public static void tearDownAfterClass() throws Exception {
92 }
93
94 @Before
95 public void setUp() throws Exception {
96 simpleLinkStore = new SimpleLinkStore();
97 simpleLinkStore.activate();
98 linkStore = simpleLinkStore;
99 }
100
101 @After
102 public void tearDown() throws Exception {
103 simpleLinkStore.deactivate();
104 }
105
106 private void putLink(DeviceId srcId, PortNumber srcNum,
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700107 DeviceId dstId, PortNumber dstNum, Type type,
108 SparseAnnotations... annotations) {
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700109 ConnectPoint src = new ConnectPoint(srcId, srcNum);
110 ConnectPoint dst = new ConnectPoint(dstId, dstNum);
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700111 linkStore.createOrUpdateLink(PID, new DefaultLinkDescription(src, dst, type, annotations));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700112 }
113
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700114 private void putLink(LinkKey key, Type type, SparseAnnotations... annotations) {
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700115 putLink(key.src().deviceId(), key.src().port(),
116 key.dst().deviceId(), key.dst().port(),
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700117 type, annotations);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700118 }
119
120 private static void assertLink(DeviceId srcId, PortNumber srcNum,
121 DeviceId dstId, PortNumber dstNum, Type type,
122 Link link) {
123 assertEquals(srcId, link.src().deviceId());
124 assertEquals(srcNum, link.src().port());
125 assertEquals(dstId, link.dst().deviceId());
126 assertEquals(dstNum, link.dst().port());
127 assertEquals(type, link.type());
128 }
129
130 private static void assertLink(LinkKey key, Type type, Link link) {
131 assertLink(key.src().deviceId(), key.src().port(),
132 key.dst().deviceId(), key.dst().port(),
133 type, link);
134 }
135
136 @Test
137 public final void testGetLinkCount() {
138 assertEquals("initialy empty", 0, linkStore.getLinkCount());
139
140 putLink(DID1, P1, DID2, P2, DIRECT);
141 putLink(DID2, P2, DID1, P1, DIRECT);
142 putLink(DID1, P1, DID2, P2, DIRECT);
143
144 assertEquals("expecting 2 unique link", 2, linkStore.getLinkCount());
145 }
146
147 @Test
148 public final void testGetLinks() {
149 assertEquals("initialy empty", 0,
150 Iterables.size(linkStore.getLinks()));
151
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700152 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
153 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700154
155 putLink(linkId1, DIRECT);
156 putLink(linkId2, DIRECT);
157 putLink(linkId1, DIRECT);
158
159 assertEquals("expecting 2 unique link", 2,
160 Iterables.size(linkStore.getLinks()));
161
162 Map<LinkKey, Link> links = new HashMap<>();
163 for (Link link : linkStore.getLinks()) {
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700164 links.put(LinkKey.linkKey(link), link);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700165 }
166
167 assertLink(linkId1, DIRECT, links.get(linkId1));
168 assertLink(linkId2, DIRECT, links.get(linkId2));
169 }
170
171 @Test
172 public final void testGetDeviceEgressLinks() {
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700173 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
174 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
175 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700176
177 putLink(linkId1, DIRECT);
178 putLink(linkId2, DIRECT);
179 putLink(linkId3, DIRECT);
180
181 // DID1,P1 => DID2,P2
182 // DID2,P2 => DID1,P1
183 // DID1,P2 => DID2,P3
184
185 Set<Link> links1 = linkStore.getDeviceEgressLinks(DID1);
186 assertEquals(2, links1.size());
187 // check
188
189 Set<Link> links2 = linkStore.getDeviceEgressLinks(DID2);
190 assertEquals(1, links2.size());
191 assertLink(linkId2, DIRECT, links2.iterator().next());
192 }
193
194 @Test
195 public final void testGetDeviceIngressLinks() {
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700196 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
197 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
198 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700199
200 putLink(linkId1, DIRECT);
201 putLink(linkId2, DIRECT);
202 putLink(linkId3, DIRECT);
203
204 // DID1,P1 => DID2,P2
205 // DID2,P2 => DID1,P1
206 // DID1,P2 => DID2,P3
207
208 Set<Link> links1 = linkStore.getDeviceIngressLinks(DID2);
209 assertEquals(2, links1.size());
210 // check
211
212 Set<Link> links2 = linkStore.getDeviceIngressLinks(DID1);
213 assertEquals(1, links2.size());
214 assertLink(linkId2, DIRECT, links2.iterator().next());
215 }
216
217 @Test
218 public final void testGetLink() {
219 ConnectPoint src = new ConnectPoint(DID1, P1);
220 ConnectPoint dst = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700221 LinkKey linkId1 = LinkKey.linkKey(src, dst);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700222
223 putLink(linkId1, DIRECT);
224
225 Link link = linkStore.getLink(src, dst);
226 assertLink(linkId1, DIRECT, link);
227
228 assertNull("There shouldn't be reverese link",
229 linkStore.getLink(dst, src));
230 }
231
232 @Test
233 public final void testGetEgressLinks() {
234 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
235 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700236 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
237 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
238 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700239
240 putLink(linkId1, DIRECT);
241 putLink(linkId2, DIRECT);
242 putLink(linkId3, DIRECT);
243
244 // DID1,P1 => DID2,P2
245 // DID2,P2 => DID1,P1
246 // DID1,P2 => DID2,P3
247
248 Set<Link> links1 = linkStore.getEgressLinks(d1P1);
249 assertEquals(1, links1.size());
250 assertLink(linkId1, DIRECT, links1.iterator().next());
251
252 Set<Link> links2 = linkStore.getEgressLinks(d2P2);
253 assertEquals(1, links2.size());
254 assertLink(linkId2, DIRECT, links2.iterator().next());
255 }
256
257 @Test
258 public final void testGetIngressLinks() {
259 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
260 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700261 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
262 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
263 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700264
265 putLink(linkId1, DIRECT);
266 putLink(linkId2, DIRECT);
267 putLink(linkId3, DIRECT);
268
269 // DID1,P1 => DID2,P2
270 // DID2,P2 => DID1,P1
271 // DID1,P2 => DID2,P3
272
273 Set<Link> links1 = linkStore.getIngressLinks(d2P2);
274 assertEquals(1, links1.size());
275 assertLink(linkId1, DIRECT, links1.iterator().next());
276
277 Set<Link> links2 = linkStore.getIngressLinks(d1P1);
278 assertEquals(1, links2.size());
279 assertLink(linkId2, DIRECT, links2.iterator().next());
280 }
281
282 @Test
283 public final void testCreateOrUpdateLink() {
284 ConnectPoint src = new ConnectPoint(DID1, P1);
285 ConnectPoint dst = new ConnectPoint(DID2, P2);
286
287 // add link
288 LinkEvent event = linkStore.createOrUpdateLink(PID,
289 new DefaultLinkDescription(src, dst, INDIRECT));
290
291 assertLink(DID1, P1, DID2, P2, INDIRECT, event.subject());
292 assertEquals(LINK_ADDED, event.type());
293
294 // update link type
295 LinkEvent event2 = linkStore.createOrUpdateLink(PID,
296 new DefaultLinkDescription(src, dst, DIRECT));
297
298 assertLink(DID1, P1, DID2, P2, DIRECT, event2.subject());
299 assertEquals(LINK_UPDATED, event2.type());
300
301 // no change
302 LinkEvent event3 = linkStore.createOrUpdateLink(PID,
303 new DefaultLinkDescription(src, dst, DIRECT));
304
305 assertNull("No change event expected", event3);
306 }
307
308 @Test
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700309 public final void testCreateOrUpdateLinkAncillary() {
310 ConnectPoint src = new ConnectPoint(DID1, P1);
311 ConnectPoint dst = new ConnectPoint(DID2, P2);
312
313 // add Ancillary link
314 LinkEvent event = linkStore.createOrUpdateLink(PIDA,
315 new DefaultLinkDescription(src, dst, INDIRECT, A1));
316
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700317 assertNotNull("Ancillary only link is ignored", event);
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700318
319 // add Primary link
320 LinkEvent event2 = linkStore.createOrUpdateLink(PID,
321 new DefaultLinkDescription(src, dst, INDIRECT, A2));
322
323 assertLink(DID1, P1, DID2, P2, INDIRECT, event2.subject());
324 assertAnnotationsEquals(event2.subject().annotations(), A2, A1);
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700325 assertEquals(LINK_UPDATED, event2.type());
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700326
327 // update link type
328 LinkEvent event3 = linkStore.createOrUpdateLink(PID,
329 new DefaultLinkDescription(src, dst, DIRECT, A2));
330 assertLink(DID1, P1, DID2, P2, DIRECT, event3.subject());
331 assertAnnotationsEquals(event3.subject().annotations(), A2, A1);
332 assertEquals(LINK_UPDATED, event3.type());
333
334
335 // no change
336 LinkEvent event4 = linkStore.createOrUpdateLink(PID,
337 new DefaultLinkDescription(src, dst, DIRECT));
338 assertNull("No change event expected", event4);
339
340 // update link annotation (Primary)
341 LinkEvent event5 = linkStore.createOrUpdateLink(PID,
342 new DefaultLinkDescription(src, dst, DIRECT, A2_2));
343 assertLink(DID1, P1, DID2, P2, DIRECT, event5.subject());
344 assertAnnotationsEquals(event5.subject().annotations(), A2, A2_2, A1);
345 assertEquals(LINK_UPDATED, event5.type());
346
347 // update link annotation (Ancillary)
348 LinkEvent event6 = linkStore.createOrUpdateLink(PIDA,
349 new DefaultLinkDescription(src, dst, DIRECT, A1_2));
350 assertLink(DID1, P1, DID2, P2, DIRECT, event6.subject());
351 assertAnnotationsEquals(event6.subject().annotations(), A2, A2_2, A1, A1_2);
352 assertEquals(LINK_UPDATED, event6.type());
353
354 // update link type (Ancillary) : ignored
355 LinkEvent event7 = linkStore.createOrUpdateLink(PIDA,
356 new DefaultLinkDescription(src, dst, EDGE));
357 assertNull("Ancillary change other than annotation is ignored", event7);
358 }
359
360
361 @Test
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700362 public final void testRemoveLink() {
363 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
364 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700365 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
366 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700367
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700368 putLink(linkId1, DIRECT, A1);
369 putLink(linkId2, DIRECT, A2);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700370
371 // DID1,P1 => DID2,P2
372 // DID2,P2 => DID1,P1
373 // DID1,P2 => DID2,P3
374
375 LinkEvent event = linkStore.removeLink(d1P1, d2P2);
376 assertEquals(LINK_REMOVED, event.type());
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700377 assertAnnotationsEquals(event.subject().annotations(), A1);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700378 LinkEvent event2 = linkStore.removeLink(d1P1, d2P2);
379 assertNull(event2);
380
381 assertLink(linkId2, DIRECT, linkStore.getLink(d2P2, d1P1));
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700382 assertAnnotationsEquals(linkStore.getLink(d2P2, d1P1).annotations(), A2);
383
384 // annotations, etc. should not survive remove
385 putLink(linkId1, DIRECT);
386 assertLink(linkId1, DIRECT, linkStore.getLink(d1P1, d2P2));
387 assertAnnotationsEquals(linkStore.getLink(d1P1, d2P2).annotations());
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700388 }
389
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700390 @Test
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700391 public final void testAncillaryVisible() {
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700392 ConnectPoint src = new ConnectPoint(DID1, P1);
393 ConnectPoint dst = new ConnectPoint(DID2, P2);
394
395 // add Ancillary link
396 linkStore.createOrUpdateLink(PIDA,
397 new DefaultLinkDescription(src, dst, INDIRECT, A1));
398
399 // Ancillary only link should not be visible
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700400 assertEquals(1, linkStore.getLinkCount());
401 assertNotNull(linkStore.getLink(src, dst));
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700402 }
403
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700404 // If Delegates should be called only on remote events,
405 // then Simple* should never call them, thus not test required.
406 @Ignore("Ignore until Delegate spec. is clear.")
407 @Test
408 public final void testEvents() throws InterruptedException {
409
410 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
411 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700412 final LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700413
414 final CountDownLatch addLatch = new CountDownLatch(1);
415 LinkStoreDelegate checkAdd = new LinkStoreDelegate() {
416 @Override
417 public void notify(LinkEvent event) {
418 assertEquals(LINK_ADDED, event.type());
419 assertLink(linkId1, INDIRECT, event.subject());
420 addLatch.countDown();
421 }
422 };
423 final CountDownLatch updateLatch = new CountDownLatch(1);
424 LinkStoreDelegate checkUpdate = new LinkStoreDelegate() {
425 @Override
426 public void notify(LinkEvent event) {
427 assertEquals(LINK_UPDATED, event.type());
428 assertLink(linkId1, DIRECT, event.subject());
429 updateLatch.countDown();
430 }
431 };
432 final CountDownLatch removeLatch = new CountDownLatch(1);
433 LinkStoreDelegate checkRemove = new LinkStoreDelegate() {
434 @Override
435 public void notify(LinkEvent event) {
436 assertEquals(LINK_REMOVED, event.type());
437 assertLink(linkId1, DIRECT, event.subject());
438 removeLatch.countDown();
439 }
440 };
441
442 linkStore.setDelegate(checkAdd);
443 putLink(linkId1, INDIRECT);
444 assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
445
446 linkStore.unsetDelegate(checkAdd);
447 linkStore.setDelegate(checkUpdate);
448 putLink(linkId1, DIRECT);
449 assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS));
450
451 linkStore.unsetDelegate(checkUpdate);
452 linkStore.setDelegate(checkRemove);
453 linkStore.removeLink(d1P1, d2P2);
454 assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS));
455 }
456}