blob: a76e901ef7de67a185f1c3132c24654fbb6276be [file] [log] [blame]
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -07001package org.onlab.onos.store.link.impl;
2
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.*;
7
8import java.util.HashMap;
9import java.util.Map;
10import java.util.Set;
11import java.util.concurrent.CountDownLatch;
12import java.util.concurrent.TimeUnit;
13
14import org.junit.After;
15import org.junit.AfterClass;
16import org.junit.Before;
17import org.junit.BeforeClass;
Yuta HIGUCHIfec9e192014-09-28 14:58:02 -070018import org.junit.Ignore;
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -070019import org.junit.Test;
20import org.onlab.onos.net.ConnectPoint;
21import org.onlab.onos.net.DeviceId;
22import org.onlab.onos.net.Link;
23import org.onlab.onos.net.LinkKey;
24import org.onlab.onos.net.PortNumber;
25import org.onlab.onos.net.Link.Type;
26import org.onlab.onos.net.link.DefaultLinkDescription;
27import org.onlab.onos.net.link.LinkEvent;
28import org.onlab.onos.net.link.LinkStoreDelegate;
29import org.onlab.onos.net.provider.ProviderId;
Yuta HIGUCHIb5df76d2014-09-27 20:54:00 -070030import org.onlab.onos.store.common.StoreManager;
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -070031import org.onlab.onos.store.common.StoreService;
Yuta HIGUCHIb5df76d2014-09-27 20:54:00 -070032import org.onlab.onos.store.common.TestStoreManager;
Yuta HIGUCHIad4c2182014-09-29 11:16:23 -070033import org.onlab.onos.store.serializers.KryoSerializationManager;
34import org.onlab.onos.store.serializers.KryoSerializationService;
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -070035
36import com.google.common.collect.Iterables;
37import com.hazelcast.config.Config;
38import com.hazelcast.core.Hazelcast;
39
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070040/**
41 * Test of the Hazelcast based distributed LinkStore implementation.
42 */
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -070043public class DistributedLinkStoreTest {
44
45 private static final ProviderId PID = new ProviderId("of", "foo");
46 private static final DeviceId DID1 = deviceId("of:foo");
47 private static final DeviceId DID2 = deviceId("of:bar");
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -070048
49 private static final PortNumber P1 = PortNumber.portNumber(1);
50 private static final PortNumber P2 = PortNumber.portNumber(2);
51 private static final PortNumber P3 = PortNumber.portNumber(3);
52
53 private StoreManager storeManager;
Yuta HIGUCHIad4c2182014-09-29 11:16:23 -070054 private KryoSerializationManager serializationMgr;
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -070055
56 private DistributedLinkStore linkStore;
57
58 @BeforeClass
59 public static void setUpBeforeClass() throws Exception {
60 }
61
62 @AfterClass
63 public static void tearDownAfterClass() throws Exception {
64 }
65
66 @Before
67 public void setUp() throws Exception {
68 // TODO should find a way to clean Hazelcast instance without shutdown.
69 Config config = TestStoreManager.getTestConfig();
70
71 storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config));
72 storeManager.activate();
73
Yuta HIGUCHIad4c2182014-09-29 11:16:23 -070074 serializationMgr = new KryoSerializationManager();
75 serializationMgr.activate();
76
77 linkStore = new TestDistributedLinkStore(storeManager, serializationMgr);
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -070078 linkStore.activate();
79 }
80
81 @After
82 public void tearDown() throws Exception {
83 linkStore.deactivate();
Yuta HIGUCHIad4c2182014-09-29 11:16:23 -070084 serializationMgr.deactivate();
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -070085 storeManager.deactivate();
86 }
87
88 private void putLink(DeviceId srcId, PortNumber srcNum,
89 DeviceId dstId, PortNumber dstNum, Type type) {
90 ConnectPoint src = new ConnectPoint(srcId, srcNum);
91 ConnectPoint dst = new ConnectPoint(dstId, dstNum);
92 linkStore.createOrUpdateLink(PID, new DefaultLinkDescription(src, dst, type));
93 }
94
95 private void putLink(LinkKey key, Type type) {
96 putLink(key.src().deviceId(), key.src().port(),
97 key.dst().deviceId(), key.dst().port(),
98 type);
99 }
100
101 private static void assertLink(DeviceId srcId, PortNumber srcNum,
102 DeviceId dstId, PortNumber dstNum, Type type,
103 Link link) {
104 assertEquals(srcId, link.src().deviceId());
105 assertEquals(srcNum, link.src().port());
106 assertEquals(dstId, link.dst().deviceId());
107 assertEquals(dstNum, link.dst().port());
108 assertEquals(type, link.type());
109 }
110
111 private static void assertLink(LinkKey key, Type type, Link link) {
112 assertLink(key.src().deviceId(), key.src().port(),
113 key.dst().deviceId(), key.dst().port(),
114 type, link);
115 }
116
117 @Test
118 public final void testGetLinkCount() {
119 assertEquals("initialy empty", 0, linkStore.getLinkCount());
120
121 putLink(DID1, P1, DID2, P2, DIRECT);
122 putLink(DID2, P2, DID1, P1, DIRECT);
123 putLink(DID1, P1, DID2, P2, DIRECT);
124
125 assertEquals("expecting 2 unique link", 2, linkStore.getLinkCount());
126 }
127
128 @Test
129 public final void testGetLinks() {
130 assertEquals("initialy empty", 0,
131 Iterables.size(linkStore.getLinks()));
132
133 LinkKey linkId1 = new LinkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
134 LinkKey linkId2 = new LinkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
135
136 putLink(linkId1, DIRECT);
137 putLink(linkId2, DIRECT);
138 putLink(linkId1, DIRECT);
139
140 assertEquals("expecting 2 unique link", 2,
141 Iterables.size(linkStore.getLinks()));
142
143 Map<LinkKey, Link> links = new HashMap<>();
144 for (Link link : linkStore.getLinks()) {
145 links.put(new LinkKey(link.src(), link.dst()), link);
146 }
147
148 assertLink(linkId1, DIRECT, links.get(linkId1));
149 assertLink(linkId2, DIRECT, links.get(linkId2));
150 }
151
152 @Test
153 public final void testGetDeviceEgressLinks() {
154 LinkKey linkId1 = new LinkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
155 LinkKey linkId2 = new LinkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
156 LinkKey linkId3 = new LinkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
157
158 putLink(linkId1, DIRECT);
159 putLink(linkId2, DIRECT);
160 putLink(linkId3, DIRECT);
161
162 // DID1,P1 => DID2,P2
163 // DID2,P2 => DID1,P1
164 // DID1,P2 => DID2,P3
165
166 Set<Link> links1 = linkStore.getDeviceEgressLinks(DID1);
167 assertEquals(2, links1.size());
168 // check
169
170 Set<Link> links2 = linkStore.getDeviceEgressLinks(DID2);
171 assertEquals(1, links2.size());
172 assertLink(linkId2, DIRECT, links2.iterator().next());
173 }
174
175 @Test
176 public final void testGetDeviceIngressLinks() {
177 LinkKey linkId1 = new LinkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2));
178 LinkKey linkId2 = new LinkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1));
179 LinkKey linkId3 = new LinkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
180
181 putLink(linkId1, DIRECT);
182 putLink(linkId2, DIRECT);
183 putLink(linkId3, DIRECT);
184
185 // DID1,P1 => DID2,P2
186 // DID2,P2 => DID1,P1
187 // DID1,P2 => DID2,P3
188
189 Set<Link> links1 = linkStore.getDeviceIngressLinks(DID2);
190 assertEquals(2, links1.size());
191 // check
192
193 Set<Link> links2 = linkStore.getDeviceIngressLinks(DID1);
194 assertEquals(1, links2.size());
195 assertLink(linkId2, DIRECT, links2.iterator().next());
196 }
197
198 @Test
199 public final void testGetLink() {
200 ConnectPoint src = new ConnectPoint(DID1, P1);
201 ConnectPoint dst = new ConnectPoint(DID2, P2);
202 LinkKey linkId1 = new LinkKey(src, dst);
203
204 putLink(linkId1, DIRECT);
205
206 Link link = linkStore.getLink(src, dst);
207 assertLink(linkId1, DIRECT, link);
208
209 assertNull("There shouldn't be reverese link",
210 linkStore.getLink(dst, src));
211 }
212
213 @Test
214 public final void testGetEgressLinks() {
215 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
216 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
217 LinkKey linkId1 = new LinkKey(d1P1, d2P2);
218 LinkKey linkId2 = new LinkKey(d2P2, d1P1);
219 LinkKey linkId3 = new LinkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
220
221 putLink(linkId1, DIRECT);
222 putLink(linkId2, DIRECT);
223 putLink(linkId3, DIRECT);
224
225 // DID1,P1 => DID2,P2
226 // DID2,P2 => DID1,P1
227 // DID1,P2 => DID2,P3
228
229 Set<Link> links1 = linkStore.getEgressLinks(d1P1);
230 assertEquals(1, links1.size());
231 assertLink(linkId1, DIRECT, links1.iterator().next());
232
233 Set<Link> links2 = linkStore.getEgressLinks(d2P2);
234 assertEquals(1, links2.size());
235 assertLink(linkId2, DIRECT, links2.iterator().next());
236 }
237
238 @Test
239 public final void testGetIngressLinks() {
240 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
241 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
242 LinkKey linkId1 = new LinkKey(d1P1, d2P2);
243 LinkKey linkId2 = new LinkKey(d2P2, d1P1);
244 LinkKey linkId3 = new LinkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3));
245
246 putLink(linkId1, DIRECT);
247 putLink(linkId2, DIRECT);
248 putLink(linkId3, DIRECT);
249
250 // DID1,P1 => DID2,P2
251 // DID2,P2 => DID1,P1
252 // DID1,P2 => DID2,P3
253
254 Set<Link> links1 = linkStore.getIngressLinks(d2P2);
255 assertEquals(1, links1.size());
256 assertLink(linkId1, DIRECT, links1.iterator().next());
257
258 Set<Link> links2 = linkStore.getIngressLinks(d1P1);
259 assertEquals(1, links2.size());
260 assertLink(linkId2, DIRECT, links2.iterator().next());
261 }
262
263 @Test
264 public final void testCreateOrUpdateLink() {
265 ConnectPoint src = new ConnectPoint(DID1, P1);
266 ConnectPoint dst = new ConnectPoint(DID2, P2);
267
268 // add link
269 LinkEvent event = linkStore.createOrUpdateLink(PID,
270 new DefaultLinkDescription(src, dst, INDIRECT));
271
272 assertLink(DID1, P1, DID2, P2, INDIRECT, event.subject());
273 assertEquals(LINK_ADDED, event.type());
274
275 // update link type
276 LinkEvent event2 = linkStore.createOrUpdateLink(PID,
277 new DefaultLinkDescription(src, dst, DIRECT));
278
279 assertLink(DID1, P1, DID2, P2, DIRECT, event2.subject());
280 assertEquals(LINK_UPDATED, event2.type());
281
282 // no change
283 LinkEvent event3 = linkStore.createOrUpdateLink(PID,
284 new DefaultLinkDescription(src, dst, DIRECT));
285
286 assertNull("No change event expected", event3);
287 }
288
289 @Test
290 public final void testRemoveLink() {
291 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
292 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
293 LinkKey linkId1 = new LinkKey(d1P1, d2P2);
294 LinkKey linkId2 = new LinkKey(d2P2, d1P1);
295
296 putLink(linkId1, DIRECT);
297 putLink(linkId2, DIRECT);
298
299 // DID1,P1 => DID2,P2
300 // DID2,P2 => DID1,P1
301 // DID1,P2 => DID2,P3
302
303 LinkEvent event = linkStore.removeLink(d1P1, d2P2);
304 assertEquals(LINK_REMOVED, event.type());
305 LinkEvent event2 = linkStore.removeLink(d1P1, d2P2);
306 assertNull(event2);
307
308 assertLink(linkId2, DIRECT, linkStore.getLink(d2P2, d1P1));
309 }
310
Yuta HIGUCHIfec9e192014-09-28 14:58:02 -0700311 @Ignore("Ignore until Delegate spec. is clear.")
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -0700312 @Test
313 public final void testEvents() throws InterruptedException {
314
315 final ConnectPoint d1P1 = new ConnectPoint(DID1, P1);
316 final ConnectPoint d2P2 = new ConnectPoint(DID2, P2);
317 final LinkKey linkId1 = new LinkKey(d1P1, d2P2);
318
319 final CountDownLatch addLatch = new CountDownLatch(1);
320 LinkStoreDelegate checkAdd = new LinkStoreDelegate() {
321 @Override
322 public void notify(LinkEvent event) {
323 assertEquals(LINK_ADDED, event.type());
324 assertLink(linkId1, INDIRECT, event.subject());
325 addLatch.countDown();
326 }
327 };
328 final CountDownLatch updateLatch = new CountDownLatch(1);
329 LinkStoreDelegate checkUpdate = new LinkStoreDelegate() {
330 @Override
331 public void notify(LinkEvent event) {
332 assertEquals(LINK_UPDATED, event.type());
333 assertLink(linkId1, DIRECT, event.subject());
334 updateLatch.countDown();
335 }
336 };
337 final CountDownLatch removeLatch = new CountDownLatch(1);
338 LinkStoreDelegate checkRemove = new LinkStoreDelegate() {
339 @Override
340 public void notify(LinkEvent event) {
341 assertEquals(LINK_REMOVED, event.type());
342 assertLink(linkId1, DIRECT, event.subject());
343 removeLatch.countDown();
344 }
345 };
346
347 linkStore.setDelegate(checkAdd);
348 putLink(linkId1, INDIRECT);
349 assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
350
351 linkStore.unsetDelegate(checkAdd);
352 linkStore.setDelegate(checkUpdate);
353 putLink(linkId1, DIRECT);
354 assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS));
355
356 linkStore.unsetDelegate(checkUpdate);
357 linkStore.setDelegate(checkRemove);
358 linkStore.removeLink(d1P1, d2P2);
359 assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS));
360 }
361
362
363 class TestDistributedLinkStore extends DistributedLinkStore {
Yuta HIGUCHIad4c2182014-09-29 11:16:23 -0700364 TestDistributedLinkStore(StoreService storeService,
365 KryoSerializationService kryoSerializationService) {
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -0700366 this.storeService = storeService;
Yuta HIGUCHIad4c2182014-09-29 11:16:23 -0700367 this.kryoSerializationService = kryoSerializationService;
Yuta HIGUCHIa8a53eb2014-09-25 17:47:55 -0700368 }
369 }
370}