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