blob: b0da3373f98e2188e503da175f12c63ce0d370b8 [file] [log] [blame]
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -08001/*
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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.store.link.impl;
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -080017
18import com.google.common.collect.Iterables;
Madan Jampani2af244a2015-02-22 13:12:01 -080019
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -080020import org.easymock.Capture;
21import org.junit.After;
22import org.junit.AfterClass;
23import org.junit.Before;
24import org.junit.BeforeClass;
25import org.junit.Ignore;
26import org.junit.Test;
Jonathan Hart7d656f42015-01-27 14:07:23 -080027import org.onlab.packet.IpAddress;
Brian O'Connorabafb502014-12-02 22:26:20 -080028import org.onosproject.cluster.ControllerNode;
29import org.onosproject.cluster.DefaultControllerNode;
30import org.onosproject.cluster.NodeId;
Marc De Leenheerb473b9d2015-02-06 15:21:03 -080031import org.onosproject.mastership.MastershipServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.mastership.MastershipTerm;
33import org.onosproject.net.ConnectPoint;
34import org.onosproject.net.DefaultAnnotations;
35import org.onosproject.net.DeviceId;
36import org.onosproject.net.Link;
37import org.onosproject.net.Link.Type;
38import org.onosproject.net.LinkKey;
39import org.onosproject.net.PortNumber;
40import org.onosproject.net.SparseAnnotations;
41import org.onosproject.net.device.DeviceClockService;
42import org.onosproject.net.link.DefaultLinkDescription;
43import org.onosproject.net.link.LinkDescription;
44import org.onosproject.net.link.LinkEvent;
45import org.onosproject.net.link.LinkStore;
46import org.onosproject.net.link.LinkStoreDelegate;
47import org.onosproject.net.provider.ProviderId;
48import org.onosproject.store.cluster.StaticClusterService;
49import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
Brian O'Connorabafb502014-12-02 22:26:20 -080050import org.onosproject.store.cluster.messaging.ClusterMessageHandler;
51import org.onosproject.store.cluster.messaging.MessageSubject;
52import org.onosproject.store.device.impl.DeviceClockManager;
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -080053
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -080054import java.util.HashMap;
55import java.util.Map;
56import java.util.Set;
57import java.util.concurrent.CountDownLatch;
Madan Jampani2af244a2015-02-22 13:12:01 -080058import java.util.concurrent.ExecutorService;
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -080059import java.util.concurrent.TimeUnit;
Madan Jampani2bfa94c2015-04-11 05:03:49 -070060import java.util.function.Function;
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -080061
Jonathan Hart7d656f42015-01-27 14:07:23 -080062import static org.easymock.EasyMock.*;
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -080063import static org.junit.Assert.*;
Brian O'Connorabafb502014-12-02 22:26:20 -080064import static org.onosproject.cluster.ControllerNode.State.ACTIVE;
65import static org.onosproject.net.DeviceId.deviceId;
Jonathan Hart7d656f42015-01-27 14:07:23 -080066import static org.onosproject.net.Link.Type.DIRECT;
67import static org.onosproject.net.Link.Type.EDGE;
68import static org.onosproject.net.Link.Type.INDIRECT;
Brian O'Connorabafb502014-12-02 22:26:20 -080069import static org.onosproject.net.NetTestTools.assertAnnotationsEquals;
Jonathan Hart7d656f42015-01-27 14:07:23 -080070import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
71import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED;
72import static org.onosproject.net.link.LinkEvent.Type.LINK_UPDATED;
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -080073
74/**
75 * Test of the GossipLinkStoreTest implementation.
76 */
77public class GossipLinkStoreTest {
78
79 private static final ProviderId PID = new ProviderId("of", "foo");
80 private static final ProviderId PIDA = new ProviderId("of", "bar", true);
81 private static final DeviceId DID1 = deviceId("of:foo");
82 private static final DeviceId DID2 = deviceId("of:bar");
83
84 private static final PortNumber P1 = PortNumber.portNumber(1);
85 private static final PortNumber P2 = PortNumber.portNumber(2);
86 private static final PortNumber P3 = PortNumber.portNumber(3);
87
88 private static final SparseAnnotations A1 = DefaultAnnotations.builder()
89 .set("A1", "a1")
90 .set("B1", "b1")
91 .build();
92 private static final SparseAnnotations A1_2 = DefaultAnnotations.builder()
93 .remove("A1")
94 .set("B3", "b3")
95 .build();
96 private static final SparseAnnotations A2 = DefaultAnnotations.builder()
97 .set("A2", "a2")
98 .set("B2", "b2")
99 .build();
100 private static final SparseAnnotations A2_2 = DefaultAnnotations.builder()
101 .remove("A2")
102 .set("B4", "b4")
103 .build();
104
105 // local node
106 private static final NodeId NID1 = new NodeId("local");
107 private static final ControllerNode ONOS1 =
108 new DefaultControllerNode(NID1, IpAddress.valueOf("127.0.0.1"));
109
110 // remote node
111 private static final NodeId NID2 = new NodeId("remote");
112 private static final ControllerNode ONOS2 =
113 new DefaultControllerNode(NID2, IpAddress.valueOf("127.0.0.2"));
114
115 private GossipLinkStore linkStoreImpl;
116 private LinkStore linkStore;
117
118 private DeviceClockManager deviceClockManager;
119 private DeviceClockService deviceClockService;
120 private ClusterCommunicationService clusterCommunicator;
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800121
122 @BeforeClass
123 public static void setUpBeforeClass() throws Exception {
124 }
125
126 @AfterClass
127 public static void tearDownAfterClass() throws Exception {
128 }
129
130 @Before
131 public void setUp() throws Exception {
132 deviceClockManager = new DeviceClockManager();
133 deviceClockManager.activate();
134 deviceClockService = deviceClockManager;
135
136 // set initial terms
137 deviceClockManager.setMastershipTerm(DID1, MastershipTerm.of(NID1, 1));
138 deviceClockManager.setMastershipTerm(DID2, MastershipTerm.of(NID1, 2));
139
140 // TODO mock clusterCommunicator
141 clusterCommunicator = createNiceMock(ClusterCommunicationService.class);
142 clusterCommunicator.addSubscriber(anyObject(MessageSubject.class),
Madan Jampani2af244a2015-02-22 13:12:01 -0800143 anyObject(ClusterMessageHandler.class),
144 anyObject(ExecutorService.class));
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800145 expectLastCall().anyTimes();
146 replay(clusterCommunicator);
147
148 linkStoreImpl = new GossipLinkStore();
149 linkStoreImpl.deviceClockService = deviceClockService;
150 linkStoreImpl.clusterCommunicator = clusterCommunicator;
151 linkStoreImpl.clusterService = new TestClusterService();
Marc De Leenheerb473b9d2015-02-06 15:21:03 -0800152 linkStoreImpl.mastershipService = new TestMastershipService();
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800153 linkStoreImpl.activate();
154 linkStore = linkStoreImpl;
155
156 verify(clusterCommunicator);
157 reset(clusterCommunicator);
Marc De Leenheerb473b9d2015-02-06 15:21:03 -0800158
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800159 }
160
161 @After
162 public void tearDown() throws Exception {
163 linkStoreImpl.deactivate();
164 }
165
166 private void putLink(DeviceId srcId, PortNumber srcNum,
167 DeviceId dstId, PortNumber dstNum, Type type,
168 SparseAnnotations... annotations) {
169 ConnectPoint src = new ConnectPoint(srcId, srcNum);
170 ConnectPoint dst = new ConnectPoint(dstId, dstNum);
171 reset(clusterCommunicator);
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700172 clusterCommunicator.<InternalLinkEvent>broadcast(
173 anyObject(InternalLinkEvent.class), anyObject(MessageSubject.class), anyObject(Function.class));
174 expectLastCall().anyTimes();
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800175 replay(clusterCommunicator);
176 linkStore.createOrUpdateLink(PID, new DefaultLinkDescription(src, dst, type, annotations));
177 verify(clusterCommunicator);
178 }
179
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700180 private <T> void resetCommunicatorExpectingSingleBroadcast(
181 Capture<T> message,
182 Capture<MessageSubject> subject,
183 Capture<Function<T, byte[]>> encoder) {
184 message.reset();
185 subject.reset();
186 encoder.reset();
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800187 reset(clusterCommunicator);
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700188 clusterCommunicator.broadcast(capture(message), capture(subject), capture(encoder));
189 expectLastCall().once();
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800190 replay(clusterCommunicator);
191 }
192
193 private void putLink(LinkKey key, Type type, SparseAnnotations... annotations) {
194 putLink(key.src().deviceId(), key.src().port(),
195 key.dst().deviceId(), key.dst().port(),
196 type, annotations);
197 }
198
199 private static void assertLink(DeviceId srcId, PortNumber srcNum,
200 DeviceId dstId, PortNumber dstNum, Type type,
201 Link link) {
202 assertEquals(srcId, link.src().deviceId());
203 assertEquals(srcNum, link.src().port());
204 assertEquals(dstId, link.dst().deviceId());
205 assertEquals(dstNum, link.dst().port());
206 assertEquals(type, link.type());
207 }
208
209 private static void assertLink(LinkKey key, Type type, Link link) {
210 assertLink(key.src().deviceId(), key.src().port(),
211 key.dst().deviceId(), key.dst().port(),
212 type, link);
213 }
214
215 @Test
216 public final void testGetLinkCount() {
217 assertEquals("initialy empty", 0, linkStore.getLinkCount());
218
219 putLink(DID1, P1, DID2, P2, DIRECT);
220 putLink(DID2, P2, DID1, P1, DIRECT);
221 putLink(DID1, P1, DID2, P2, DIRECT);
222
223 assertEquals("expecting 2 unique link", 2, linkStore.getLinkCount());
224 }
225
226 @Test
227 public final void testGetLinks() {
228 assertEquals("initialy empty", 0,
229 Iterables.size(linkStore.getLinks()));
230
231 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
232 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
233
234 putLink(linkId1, DIRECT);
235 putLink(linkId2, DIRECT);
236 putLink(linkId1, DIRECT);
237
238 assertEquals("expecting 2 unique link", 2,
239 Iterables.size(linkStore.getLinks()));
240
241 Map<LinkKey, Link> links = new HashMap<>();
242 for (Link link : linkStore.getLinks()) {
243 links.put(LinkKey.linkKey(link), link);
244 }
245
246 assertLink(linkId1, DIRECT, links.get(linkId1));
247 assertLink(linkId2, DIRECT, links.get(linkId2));
248 }
249
250 @Test
251 public final void testGetDeviceEgressLinks() {
252 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
253 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
254 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
255
256 putLink(linkId1, DIRECT);
257 putLink(linkId2, DIRECT);
258 putLink(linkId3, DIRECT);
259
260 // DID1,P1 => DID2,P2
261 // DID2,P2 => DID1,P1
262 // DID1,P2 => DID2,P3
263
264 Set<Link> links1 = linkStore.getDeviceEgressLinks(DID1);
265 assertEquals(2, links1.size());
266 // check
267
268 Set<Link> links2 = linkStore.getDeviceEgressLinks(DID2);
269 assertEquals(1, links2.size());
270 assertLink(linkId2, DIRECT, links2.iterator().next());
271 }
272
273 @Test
274 public final void testGetDeviceIngressLinks() {
275 LinkKey linkId1 = LinkKey.linkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
276 LinkKey linkId2 = LinkKey.linkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
277 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
278
279 putLink(linkId1, DIRECT);
280 putLink(linkId2, DIRECT);
281 putLink(linkId3, DIRECT);
282
283 // DID1,P1 => DID2,P2
284 // DID2,P2 => DID1,P1
285 // DID1,P2 => DID2,P3
286
287 Set<Link> links1 = linkStore.getDeviceIngressLinks(DID2);
288 assertEquals(2, links1.size());
289 // check
290
291 Set<Link> links2 = linkStore.getDeviceIngressLinks(DID1);
292 assertEquals(1, links2.size());
293 assertLink(linkId2, DIRECT, links2.iterator().next());
294 }
295
296 @Test
297 public final void testGetLink() {
298 ConnectPoint src = new ConnectPoint(DID1, P1);
299 ConnectPoint dst = new ConnectPoint(DID2, P2);
300 LinkKey linkId1 = LinkKey.linkKey(src, dst);
301
302 putLink(linkId1, DIRECT);
303
304 Link link = linkStore.getLink(src, dst);
305 assertLink(linkId1, DIRECT, link);
306
307 assertNull("There shouldn't be reverese link",
308 linkStore.getLink(dst, src));
309 }
310
311 @Test
312 public final void testGetEgressLinks() {
313 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
314 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
315 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
316 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
317 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
318
319 putLink(linkId1, DIRECT);
320 putLink(linkId2, DIRECT);
321 putLink(linkId3, DIRECT);
322
323 // DID1,P1 => DID2,P2
324 // DID2,P2 => DID1,P1
325 // DID1,P2 => DID2,P3
326
327 Set<Link> links1 = linkStore.getEgressLinks(d1P1);
328 assertEquals(1, links1.size());
329 assertLink(linkId1, DIRECT, links1.iterator().next());
330
331 Set<Link> links2 = linkStore.getEgressLinks(d2P2);
332 assertEquals(1, links2.size());
333 assertLink(linkId2, DIRECT, links2.iterator().next());
334 }
335
336 @Test
337 public final void testGetIngressLinks() {
338 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
339 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
340 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
341 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
342 LinkKey linkId3 = LinkKey.linkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
343
344 putLink(linkId1, DIRECT);
345 putLink(linkId2, DIRECT);
346 putLink(linkId3, DIRECT);
347
348 // DID1,P1 => DID2,P2
349 // DID2,P2 => DID1,P1
350 // DID1,P2 => DID2,P3
351
352 Set<Link> links1 = linkStore.getIngressLinks(d2P2);
353 assertEquals(1, links1.size());
354 assertLink(linkId1, DIRECT, links1.iterator().next());
355
356 Set<Link> links2 = linkStore.getIngressLinks(d1P1);
357 assertEquals(1, links2.size());
358 assertLink(linkId2, DIRECT, links2.iterator().next());
359 }
360
361 @Test
362 public final void testCreateOrUpdateLink() {
363 ConnectPoint src = new ConnectPoint(DID1, P1);
364 ConnectPoint dst = new ConnectPoint(DID2, P2);
365
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700366 Capture<InternalLinkEvent> message = new Capture<>();
367 Capture<MessageSubject> subject = new Capture<>();
368 Capture<Function<InternalLinkEvent, byte[]>> encoder = new Capture<>();
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800369
370 // add link
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700371 resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800372 final DefaultLinkDescription linkDescription = new DefaultLinkDescription(src, dst, INDIRECT);
373 LinkEvent event = linkStore.createOrUpdateLink(PID,
374 linkDescription);
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700375 verifyLinkBroadcastMessage(PID, NID1, src, dst, INDIRECT, message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800376
377 assertLink(DID1, P1, DID2, P2, INDIRECT, event.subject());
378 assertEquals(LINK_ADDED, event.type());
379
380 // update link type
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700381 resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800382 LinkEvent event2 = linkStore.createOrUpdateLink(PID,
383 new DefaultLinkDescription(src, dst, DIRECT));
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700384 verifyLinkBroadcastMessage(PID, NID1, src, dst, DIRECT, message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800385
386 assertLink(DID1, P1, DID2, P2, DIRECT, event2.subject());
387 assertEquals(LINK_UPDATED, event2.type());
388
389 // no change
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700390 resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800391 LinkEvent event3 = linkStore.createOrUpdateLink(PID,
392 new DefaultLinkDescription(src, dst, DIRECT));
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700393 verifyNoBroadcastMessage(message);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800394
395 assertNull("No change event expected", event3);
396 }
397
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700398 private <T> void verifyNoBroadcastMessage(Capture<T> message) {
399 assertFalse("No broadcast expected", message.hasCaptured());
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800400 }
401
402 private void verifyLinkBroadcastMessage(ProviderId providerId,
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700403 NodeId sender,
404 ConnectPoint src,
405 ConnectPoint dst,
406 Type type,
407 Capture<InternalLinkEvent> actualLinkEvent,
408 Capture<MessageSubject> actualSubject,
409 Capture<Function<InternalLinkEvent, byte[]>> actualEncoder) {
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800410 verify(clusterCommunicator);
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700411 assertTrue(actualLinkEvent.hasCaptured());
412 assertEquals(GossipLinkStoreMessageSubjects.LINK_UPDATE, actualSubject.getValue());
413 assertEquals(providerId, actualLinkEvent.getValue().providerId());
414 assertLinkDescriptionEquals(src, dst, type, actualLinkEvent.getValue().linkDescription().value());
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800415 }
416
417 private static void assertLinkDescriptionEquals(ConnectPoint src,
418 ConnectPoint dst,
419 Type type,
420 LinkDescription actual) {
421 assertEquals(src, actual.src());
422 assertEquals(dst, actual.dst());
423 assertEquals(type, actual.type());
424 // TODO check annotations
425 }
426
427 @Test
428 public final void testCreateOrUpdateLinkAncillary() {
429 ConnectPoint src = new ConnectPoint(DID1, P1);
430 ConnectPoint dst = new ConnectPoint(DID2, P2);
431
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700432 Capture<InternalLinkEvent> message = new Capture<>();
433 Capture<MessageSubject> subject = new Capture<>();
434 Capture<Function<InternalLinkEvent, byte[]>> encoder = new Capture<>();
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800435
436 // add Ancillary link
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700437 resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800438 LinkEvent event = linkStore.createOrUpdateLink(PIDA,
439 new DefaultLinkDescription(src, dst, INDIRECT, A1));
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700440 verifyLinkBroadcastMessage(PIDA, NID1, src, dst, INDIRECT, message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800441
442 assertNotNull("Ancillary only link is ignored", event);
443
444 // add Primary link
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700445 resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800446 LinkEvent event2 = linkStore.createOrUpdateLink(PID,
447 new DefaultLinkDescription(src, dst, INDIRECT, A2));
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700448 verifyLinkBroadcastMessage(PID, NID1, src, dst, INDIRECT, message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800449
450 assertLink(DID1, P1, DID2, P2, INDIRECT, event2.subject());
451 assertAnnotationsEquals(event2.subject().annotations(), A2, A1);
452 assertEquals(LINK_UPDATED, event2.type());
453
454 // update link type
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700455 resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800456 LinkEvent event3 = linkStore.createOrUpdateLink(PID,
457 new DefaultLinkDescription(src, dst, DIRECT, A2));
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700458 verifyLinkBroadcastMessage(PID, NID1, src, dst, DIRECT, message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800459
460 assertLink(DID1, P1, DID2, P2, DIRECT, event3.subject());
461 assertAnnotationsEquals(event3.subject().annotations(), A2, A1);
462 assertEquals(LINK_UPDATED, event3.type());
463
464
465 // no change
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700466 resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800467 LinkEvent event4 = linkStore.createOrUpdateLink(PID,
468 new DefaultLinkDescription(src, dst, DIRECT));
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700469 verifyNoBroadcastMessage(message);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800470
471 assertNull("No change event expected", event4);
472
473 // update link annotation (Primary)
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700474 resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800475 LinkEvent event5 = linkStore.createOrUpdateLink(PID,
476 new DefaultLinkDescription(src, dst, DIRECT, A2_2));
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700477 verifyLinkBroadcastMessage(PID, NID1, src, dst, DIRECT, message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800478
479 assertLink(DID1, P1, DID2, P2, DIRECT, event5.subject());
480 assertAnnotationsEquals(event5.subject().annotations(), A2, A2_2, A1);
481 assertEquals(LINK_UPDATED, event5.type());
482
483 // update link annotation (Ancillary)
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700484 resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800485 LinkEvent event6 = linkStore.createOrUpdateLink(PIDA,
486 new DefaultLinkDescription(src, dst, DIRECT, A1_2));
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700487 verifyLinkBroadcastMessage(PIDA, NID1, src, dst, DIRECT, message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800488
489 assertLink(DID1, P1, DID2, P2, DIRECT, event6.subject());
490 assertAnnotationsEquals(event6.subject().annotations(), A2, A2_2, A1, A1_2);
491 assertEquals(LINK_UPDATED, event6.type());
492
493 // update link type (Ancillary) : ignored
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700494 resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800495 LinkEvent event7 = linkStore.createOrUpdateLink(PIDA,
496 new DefaultLinkDescription(src, dst, EDGE));
Madan Jampani2bfa94c2015-04-11 05:03:49 -0700497 verifyNoBroadcastMessage(message);
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800498 assertNull("Ancillary change other than annotation is ignored", event7);
499 }
500
501
502 @Test
503 public final void testRemoveLink() {
504 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
505 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
506 LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
507 LinkKey linkId2 = LinkKey.linkKey(d2P2, d1P1);
508
509 putLink(linkId1, DIRECT, A1);
510 putLink(linkId2, DIRECT, A2);
511
512 // DID1,P1 => DID2,P2
513 // DID2,P2 => DID1,P1
514 // DID1,P2 => DID2,P3
515
516 LinkEvent event = linkStore.removeLink(d1P1, d2P2);
517 assertEquals(LINK_REMOVED, event.type());
518 assertAnnotationsEquals(event.subject().annotations(), A1);
519 LinkEvent event2 = linkStore.removeLink(d1P1, d2P2);
520 assertNull(event2);
521
522 assertLink(linkId2, DIRECT, linkStore.getLink(d2P2, d1P1));
523 assertAnnotationsEquals(linkStore.getLink(d2P2, d1P1).annotations(), A2);
524
525 // annotations, etc. should not survive remove
526 putLink(linkId1, DIRECT);
527 assertLink(linkId1, DIRECT, linkStore.getLink(d1P1, d2P2));
528 assertAnnotationsEquals(linkStore.getLink(d1P1, d2P2).annotations());
529 }
530
531 @Test
532 public final void testAncillaryVisible() {
533 ConnectPoint src = new ConnectPoint(DID1, P1);
534 ConnectPoint dst = new ConnectPoint(DID2, P2);
535
536 // add Ancillary link
537 linkStore.createOrUpdateLink(PIDA,
538 new DefaultLinkDescription(src, dst, INDIRECT, A1));
539
540 // Ancillary only link should not be visible
541 assertEquals(1, linkStore.getLinkCount());
542 assertNotNull(linkStore.getLink(src, dst));
543 }
544
545 // If Delegates should be called only on remote events,
546 // then Simple* should never call them, thus not test required.
547 @Ignore("Ignore until Delegate spec. is clear.")
548 @Test
549 public final void testEvents() throws InterruptedException {
550
551 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
552 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
553 final LinkKey linkId1 = LinkKey.linkKey(d1P1, d2P2);
554
555 final CountDownLatch addLatch = new CountDownLatch(1);
556 LinkStoreDelegate checkAdd = new LinkStoreDelegate() {
557 @Override
558 public void notify(LinkEvent event) {
559 assertEquals(LINK_ADDED, event.type());
560 assertLink(linkId1, INDIRECT, event.subject());
561 addLatch.countDown();
562 }
563 };
564 final CountDownLatch updateLatch = new CountDownLatch(1);
565 LinkStoreDelegate checkUpdate = new LinkStoreDelegate() {
566 @Override
567 public void notify(LinkEvent event) {
568 assertEquals(LINK_UPDATED, event.type());
569 assertLink(linkId1, DIRECT, event.subject());
570 updateLatch.countDown();
571 }
572 };
573 final CountDownLatch removeLatch = new CountDownLatch(1);
574 LinkStoreDelegate checkRemove = new LinkStoreDelegate() {
575 @Override
576 public void notify(LinkEvent event) {
577 assertEquals(LINK_REMOVED, event.type());
578 assertLink(linkId1, DIRECT, event.subject());
579 removeLatch.countDown();
580 }
581 };
582
583 linkStore.setDelegate(checkAdd);
584 putLink(linkId1, INDIRECT);
585 assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
586
587 linkStore.unsetDelegate(checkAdd);
588 linkStore.setDelegate(checkUpdate);
589 putLink(linkId1, DIRECT);
590 assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS));
591
592 linkStore.unsetDelegate(checkUpdate);
593 linkStore.setDelegate(checkRemove);
594 linkStore.removeLink(d1P1, d2P2);
595 assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS));
596 }
597
598 private static final class TestClusterService extends StaticClusterService {
599
600 public TestClusterService() {
601 localNode = ONOS1;
602 nodes.put(NID1, ONOS1);
603 nodeStates.put(NID1, ACTIVE);
604
605 nodes.put(NID2, ONOS2);
606 nodeStates.put(NID2, ACTIVE);
607 }
608 }
Marc De Leenheerb473b9d2015-02-06 15:21:03 -0800609
610 private final class TestMastershipService extends MastershipServiceAdapter {
611 @Override
612 public NodeId getMasterFor(DeviceId deviceId) {
613 return NID1;
614 }
615 }
Yuta HIGUCHI3e5d11a2014-11-04 14:16:44 -0800616}