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