blob: 735f99ca2912a21468831ec62cc877557ab6b778 [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 HIGUCHI3e5d11a2014-11-04 14:16:44 -080019
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070020import org.junit.After;
21import org.junit.AfterClass;
22import org.junit.Before;
23import org.junit.BeforeClass;
24import org.junit.Ignore;
25import org.junit.Test;
26import org.onlab.onos.net.ConnectPoint;
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070027import org.onlab.onos.net.DefaultAnnotations;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070028import org.onlab.onos.net.DeviceId;
29import org.onlab.onos.net.Link;
Thomas Vachuska0e752bd2014-10-22 22:33:41 -070030import org.onlab.onos.net.Link.Type;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070031import org.onlab.onos.net.LinkKey;
32import org.onlab.onos.net.PortNumber;
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070033import org.onlab.onos.net.SparseAnnotations;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070034import org.onlab.onos.net.link.DefaultLinkDescription;
35import org.onlab.onos.net.link.LinkEvent;
36import org.onlab.onos.net.link.LinkStore;
37import org.onlab.onos.net.link.LinkStoreDelegate;
38import org.onlab.onos.net.provider.ProviderId;
39
Thomas Vachuska0e752bd2014-10-22 22:33:41 -070040import java.util.HashMap;
41import java.util.Map;
42import java.util.Set;
43import java.util.concurrent.CountDownLatch;
44import java.util.concurrent.TimeUnit;
45
46import static org.junit.Assert.*;
47import static org.onlab.onos.net.DeviceId.deviceId;
48import static org.onlab.onos.net.Link.Type.*;
49import static org.onlab.onos.net.link.LinkEvent.Type.*;
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -080050import static org.onlab.onos.net.NetTestTools.assertAnnotationsEquals;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070051
52/**
53 * Test of the simple LinkStore implementation.
54 */
55public class SimpleLinkStoreTest {
56
57 private static final ProviderId PID = new ProviderId("of", "foo");
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070058 private static final ProviderId PIDA = new ProviderId("of", "bar", true);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070059 private static final DeviceId DID1 = deviceId("of:foo");
60 private static final DeviceId DID2 = deviceId("of:bar");
61
62 private static final PortNumber P1 = PortNumber.portNumber(1);
63 private static final PortNumber P2 = PortNumber.portNumber(2);
64 private static final PortNumber P3 = PortNumber.portNumber(3);
65
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -070066 private static final SparseAnnotations A1 = DefaultAnnotations.builder()
67 .set("A1", "a1")
68 .set("B1", "b1")
69 .build();
70 private static final SparseAnnotations A1_2 = DefaultAnnotations.builder()
71 .remove("A1")
72 .set("B3", "b3")
73 .build();
74 private static final SparseAnnotations A2 = DefaultAnnotations.builder()
75 .set("A2", "a2")
76 .set("B2", "b2")
77 .build();
78 private static final SparseAnnotations A2_2 = DefaultAnnotations.builder()
79 .remove("A2")
80 .set("B4", "b4")
81 .build();
82
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070083
84 private SimpleLinkStore simpleLinkStore;
85 private LinkStore linkStore;
86
87 @BeforeClass
88 public static void setUpBeforeClass() throws Exception {
89 }
90
91 @AfterClass
92 public static void tearDownAfterClass() throws Exception {
93 }
94
95 @Before
96 public void setUp() throws Exception {
97 simpleLinkStore = new SimpleLinkStore();
98 simpleLinkStore.activate();
99 linkStore = simpleLinkStore;
100 }
101
102 @After
103 public void tearDown() throws Exception {
104 simpleLinkStore.deactivate();
105 }
106
107 private void putLink(DeviceId srcId, PortNumber srcNum,
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700108 DeviceId dstId, PortNumber dstNum, Type type,
109 SparseAnnotations... annotations) {
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700110 ConnectPoint src = new ConnectPoint(srcId, srcNum);
111 ConnectPoint dst = new ConnectPoint(dstId, dstNum);
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700112 linkStore.createOrUpdateLink(PID, new DefaultLinkDescription(src, dst, type, annotations));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700113 }
114
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700115 private void putLink(LinkKey key, Type type, SparseAnnotations... annotations) {
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700116 putLink(key.src().deviceId(), key.src().port(),
117 key.dst().deviceId(), key.dst().port(),
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700118 type, annotations);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700119 }
120
121 private static void assertLink(DeviceId srcId, PortNumber srcNum,
122 DeviceId dstId, PortNumber dstNum, Type type,
123 Link link) {
124 assertEquals(srcId, link.src().deviceId());
125 assertEquals(srcNum, link.src().port());
126 assertEquals(dstId, link.dst().deviceId());
127 assertEquals(dstNum, link.dst().port());
128 assertEquals(type, link.type());
129 }
130
131 private static void assertLink(LinkKey key, Type type, Link link) {
132 assertLink(key.src().deviceId(), key.src().port(),
133 key.dst().deviceId(), key.dst().port(),
134 type, link);
135 }
136
137 @Test
138 public final void testGetLinkCount() {
139 assertEquals("initialy empty", 0, linkStore.getLinkCount());
140
141 putLink(DID1, P1, DID2, P2, DIRECT);
142 putLink(DID2, P2, DID1, P1, DIRECT);
143 putLink(DID1, P1, DID2, P2, DIRECT);
144
145 assertEquals("expecting 2 unique link", 2, linkStore.getLinkCount());
146 }
147
148 @Test
149 public final void testGetLinks() {
150 assertEquals("initialy empty", 0,
151 Iterables.size(linkStore.getLinks()));
152
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700153 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
154 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700155
156 putLink(linkId1, DIRECT);
157 putLink(linkId2, DIRECT);
158 putLink(linkId1, DIRECT);
159
160 assertEquals("expecting 2 unique link", 2,
161 Iterables.size(linkStore.getLinks()));
162
163 Map<LinkKey, Link> links = new HashMap<>();
164 for (Link link : linkStore.getLinks()) {
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700165 links.put(LinkKey.linkKey(link), link);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700166 }
167
168 assertLink(linkId1, DIRECT, links.get(linkId1));
169 assertLink(linkId2, DIRECT, links.get(linkId2));
170 }
171
172 @Test
173 public final void testGetDeviceEgressLinks() {
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700174 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
175 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
176 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700177
178 putLink(linkId1, DIRECT);
179 putLink(linkId2, DIRECT);
180 putLink(linkId3, DIRECT);
181
182 // DID1,P1 => DID2,P2
183 // DID2,P2 => DID1,P1
184 // DID1,P2 => DID2,P3
185
186 Set<Link> links1 = linkStore.getDeviceEgressLinks(DID1);
187 assertEquals(2, links1.size());
188 // check
189
190 Set<Link> links2 = linkStore.getDeviceEgressLinks(DID2);
191 assertEquals(1, links2.size());
192 assertLink(linkId2, DIRECT, links2.iterator().next());
193 }
194
195 @Test
196 public final void testGetDeviceIngressLinks() {
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700197 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
198 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
199 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700200
201 putLink(linkId1, DIRECT);
202 putLink(linkId2, DIRECT);
203 putLink(linkId3, DIRECT);
204
205 // DID1,P1 => DID2,P2
206 // DID2,P2 => DID1,P1
207 // DID1,P2 => DID2,P3
208
209 Set<Link> links1 = linkStore.getDeviceIngressLinks(DID2);
210 assertEquals(2, links1.size());
211 // check
212
213 Set<Link> links2 = linkStore.getDeviceIngressLinks(DID1);
214 assertEquals(1, links2.size());
215 assertLink(linkId2, DIRECT, links2.iterator().next());
216 }
217
218 @Test
219 public final void testGetLink() {
220 ConnectPoint src = new ConnectPoint(DID1, P1);
221 ConnectPoint dst = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700222 LinkKey linkId1 = LinkKey.linkKey(src, dst);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700223
224 putLink(linkId1, DIRECT);
225
226 Link link = linkStore.getLink(src, dst);
227 assertLink(linkId1, DIRECT, link);
228
229 assertNull("There shouldn't be reverese link",
230 linkStore.getLink(dst, src));
231 }
232
233 @Test
234 public final void testGetEgressLinks() {
235 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
236 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700237 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
238 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
239 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700240
241 putLink(linkId1, DIRECT);
242 putLink(linkId2, DIRECT);
243 putLink(linkId3, DIRECT);
244
245 // DID1,P1 => DID2,P2
246 // DID2,P2 => DID1,P1
247 // DID1,P2 => DID2,P3
248
249 Set<Link> links1 = linkStore.getEgressLinks(d1P1);
250 assertEquals(1, links1.size());
251 assertLink(linkId1, DIRECT, links1.iterator().next());
252
253 Set<Link> links2 = linkStore.getEgressLinks(d2P2);
254 assertEquals(1, links2.size());
255 assertLink(linkId2, DIRECT, links2.iterator().next());
256 }
257
258 @Test
259 public final void testGetIngressLinks() {
260 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
261 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700262 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
263 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
264 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700265
266 putLink(linkId1, DIRECT);
267 putLink(linkId2, DIRECT);
268 putLink(linkId3, DIRECT);
269
270 // DID1,P1 => DID2,P2
271 // DID2,P2 => DID1,P1
272 // DID1,P2 => DID2,P3
273
274 Set<Link> links1 = linkStore.getIngressLinks(d2P2);
275 assertEquals(1, links1.size());
276 assertLink(linkId1, DIRECT, links1.iterator().next());
277
278 Set<Link> links2 = linkStore.getIngressLinks(d1P1);
279 assertEquals(1, links2.size());
280 assertLink(linkId2, DIRECT, links2.iterator().next());
281 }
282
283 @Test
284 public final void testCreateOrUpdateLink() {
285 ConnectPoint src = new ConnectPoint(DID1, P1);
286 ConnectPoint dst = new ConnectPoint(DID2, P2);
287
288 // add link
289 LinkEvent event = linkStore.createOrUpdateLink(PID,
290 new DefaultLinkDescription(src, dst, INDIRECT));
291
292 assertLink(DID1, P1, DID2, P2, INDIRECT, event.subject());
293 assertEquals(LINK_ADDED, event.type());
294
295 // update link type
296 LinkEvent event2 = linkStore.createOrUpdateLink(PID,
297 new DefaultLinkDescription(src, dst, DIRECT));
298
299 assertLink(DID1, P1, DID2, P2, DIRECT, event2.subject());
300 assertEquals(LINK_UPDATED, event2.type());
301
302 // no change
303 LinkEvent event3 = linkStore.createOrUpdateLink(PID,
304 new DefaultLinkDescription(src, dst, DIRECT));
305
306 assertNull("No change event expected", event3);
307 }
308
309 @Test
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700310 public final void testCreateOrUpdateLinkAncillary() {
311 ConnectPoint src = new ConnectPoint(DID1, P1);
312 ConnectPoint dst = new ConnectPoint(DID2, P2);
313
314 // add Ancillary link
315 LinkEvent event = linkStore.createOrUpdateLink(PIDA,
316 new DefaultLinkDescription(src, dst, INDIRECT, A1));
317
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700318 assertNotNull("Ancillary only link is ignored", event);
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700319
320 // add Primary link
321 LinkEvent event2 = linkStore.createOrUpdateLink(PID,
322 new DefaultLinkDescription(src, dst, INDIRECT, A2));
323
324 assertLink(DID1, P1, DID2, P2, INDIRECT, event2.subject());
325 assertAnnotationsEquals(event2.subject().annotations(), A2, A1);
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700326 assertEquals(LINK_UPDATED, event2.type());
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700327
328 // update link type
329 LinkEvent event3 = linkStore.createOrUpdateLink(PID,
330 new DefaultLinkDescription(src, dst, DIRECT, A2));
331 assertLink(DID1, P1, DID2, P2, DIRECT, event3.subject());
332 assertAnnotationsEquals(event3.subject().annotations(), A2, A1);
333 assertEquals(LINK_UPDATED, event3.type());
334
335
336 // no change
337 LinkEvent event4 = linkStore.createOrUpdateLink(PID,
338 new DefaultLinkDescription(src, dst, DIRECT));
339 assertNull("No change event expected", event4);
340
341 // update link annotation (Primary)
342 LinkEvent event5 = linkStore.createOrUpdateLink(PID,
343 new DefaultLinkDescription(src, dst, DIRECT, A2_2));
344 assertLink(DID1, P1, DID2, P2, DIRECT, event5.subject());
345 assertAnnotationsEquals(event5.subject().annotations(), A2, A2_2, A1);
346 assertEquals(LINK_UPDATED, event5.type());
347
348 // update link annotation (Ancillary)
349 LinkEvent event6 = linkStore.createOrUpdateLink(PIDA,
350 new DefaultLinkDescription(src, dst, DIRECT, A1_2));
351 assertLink(DID1, P1, DID2, P2, DIRECT, event6.subject());
352 assertAnnotationsEquals(event6.subject().annotations(), A2, A2_2, A1, A1_2);
353 assertEquals(LINK_UPDATED, event6.type());
354
355 // update link type (Ancillary) : ignored
356 LinkEvent event7 = linkStore.createOrUpdateLink(PIDA,
357 new DefaultLinkDescription(src, dst, EDGE));
358 assertNull("Ancillary change other than annotation is ignored", event7);
359 }
360
361
362 @Test
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700363 public final void testRemoveLink() {
364 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
365 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700366 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
367 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700368
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700369 putLink(linkId1, DIRECT, A1);
370 putLink(linkId2, DIRECT, A2);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700371
372 // DID1,P1 => DID2,P2
373 // DID2,P2 => DID1,P1
374 // DID1,P2 => DID2,P3
375
376 LinkEvent event = linkStore.removeLink(d1P1, d2P2);
377 assertEquals(LINK_REMOVED, event.type());
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700378 assertAnnotationsEquals(event.subject().annotations(), A1);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700379 LinkEvent event2 = linkStore.removeLink(d1P1, d2P2);
380 assertNull(event2);
381
382 assertLink(linkId2, DIRECT, linkStore.getLink(d2P2, d1P1));
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700383 assertAnnotationsEquals(linkStore.getLink(d2P2, d1P1).annotations(), A2);
384
385 // annotations, etc. should not survive remove
386 putLink(linkId1, DIRECT);
387 assertLink(linkId1, DIRECT, linkStore.getLink(d1P1, d2P2));
388 assertAnnotationsEquals(linkStore.getLink(d1P1, d2P2).annotations());
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700389 }
390
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700391 @Test
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700392 public final void testAncillaryVisible() {
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700393 ConnectPoint src = new ConnectPoint(DID1, P1);
394 ConnectPoint dst = new ConnectPoint(DID2, P2);
395
396 // add Ancillary link
397 linkStore.createOrUpdateLink(PIDA,
398 new DefaultLinkDescription(src, dst, INDIRECT, A1));
399
400 // Ancillary only link should not be visible
Thomas Vachuska0e752bd2014-10-22 22:33:41 -0700401 assertEquals(1, linkStore.getLinkCount());
402 assertNotNull(linkStore.getLink(src, dst));
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700403 }
404
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700405 // If Delegates should be called only on remote events,
406 // then Simple* should never call them, thus not test required.
407 @Ignore("Ignore until Delegate spec. is clear.")
408 @Test
409 public final void testEvents() throws InterruptedException {
410
411 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
412 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
Yuta HIGUCHI18ab8a92014-10-13 11:16:19 -0700413 final LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700414
415 final CountDownLatch addLatch = new CountDownLatch(1);
416 LinkStoreDelegate checkAdd = new LinkStoreDelegate() {
417 @Override
418 public void notify(LinkEvent event) {
419 assertEquals(LINK_ADDED, event.type());
420 assertLink(linkId1, INDIRECT, event.subject());
421 addLatch.countDown();
422 }
423 };
424 final CountDownLatch updateLatch = new CountDownLatch(1);
425 LinkStoreDelegate checkUpdate = new LinkStoreDelegate() {
426 @Override
427 public void notify(LinkEvent event) {
428 assertEquals(LINK_UPDATED, event.type());
429 assertLink(linkId1, DIRECT, event.subject());
430 updateLatch.countDown();
431 }
432 };
433 final CountDownLatch removeLatch = new CountDownLatch(1);
434 LinkStoreDelegate checkRemove = new LinkStoreDelegate() {
435 @Override
436 public void notify(LinkEvent event) {
437 assertEquals(LINK_REMOVED, event.type());
438 assertLink(linkId1, DIRECT, event.subject());
439 removeLatch.countDown();
440 }
441 };
442
443 linkStore.setDelegate(checkAdd);
444 putLink(linkId1, INDIRECT);
445 assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
446
447 linkStore.unsetDelegate(checkAdd);
448 linkStore.setDelegate(checkUpdate);
449 putLink(linkId1, DIRECT);
450 assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS));
451
452 linkStore.unsetDelegate(checkUpdate);
453 linkStore.setDelegate(checkRemove);
454 linkStore.removeLink(d1P1, d2P2);
455 assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS));
456 }
457}