blob: e72179d037c0ce24cf9a25383c566595b22c6c08 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001package net.floodlightcontroller.topology;
2
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.HashSet;
6import java.util.List;
7import java.util.Set;
8import static org.junit.Assert.*;
9
10import net.floodlightcontroller.core.IFloodlightProviderService;
11import net.floodlightcontroller.core.module.FloodlightModuleContext;
12import net.floodlightcontroller.core.test.MockFloodlightProvider;
13import net.floodlightcontroller.core.test.MockThreadPoolService;
14import net.floodlightcontroller.linkdiscovery.ILinkDiscovery;
15import net.floodlightcontroller.threadpool.IThreadPoolService;
16import net.floodlightcontroller.topology.NodePortTuple;
17import net.floodlightcontroller.topology.TopologyInstance;
18import net.floodlightcontroller.topology.TopologyManager;
19
20import org.junit.Before;
21import org.junit.Test;
22import org.slf4j.Logger;
23import org.slf4j.LoggerFactory;
24
25public class TopologyInstanceTest {
26 protected static Logger log = LoggerFactory.getLogger(TopologyInstanceTest.class);
27 protected TopologyManager topologyManager;
28 protected FloodlightModuleContext fmc;
29 protected MockFloodlightProvider mockFloodlightProvider;
30
31 protected int DIRECT_LINK = 1;
32 protected int MULTIHOP_LINK = 2;
33 protected int TUNNEL_LINK = 3;
34
35 @Before
36 public void SetUp() throws Exception {
37 fmc = new FloodlightModuleContext();
38 mockFloodlightProvider = new MockFloodlightProvider();
39 fmc.addService(IFloodlightProviderService.class, mockFloodlightProvider);
40 MockThreadPoolService tp = new MockThreadPoolService();
41 topologyManager = new TopologyManager();
42 fmc.addService(IThreadPoolService.class, tp);
43 topologyManager.init(fmc);
44 tp.init(fmc);
45 tp.startUp(fmc);
46 }
47
48 protected void verifyClusters(int[][] clusters) {
49 verifyClusters(clusters, true);
50 }
51
52 protected void verifyClusters(int[][] clusters, boolean tunnelsEnabled) {
53 List<Long> verifiedSwitches = new ArrayList<Long>();
54
55 // Make sure the expected cluster arrays are sorted so we can
56 // use binarySearch to test for membership
57 for (int i = 0; i < clusters.length; i++)
58 Arrays.sort(clusters[i]);
59
60 TopologyInstance ti =
61 topologyManager.getCurrentInstance(tunnelsEnabled);
62 Set<Long> switches = ti.getSwitches();
63
64 for (long sw: switches) {
65 if (!verifiedSwitches.contains(sw)) {
66
67 int[] expectedCluster = null;
68
69 for (int j = 0; j < clusters.length; j++) {
70 if (Arrays.binarySearch(clusters[j], (int) sw) >= 0) {
71 expectedCluster = clusters[j];
72 break;
73 }
74 }
75 if (expectedCluster != null) {
76 Set<Long> cluster = ti.getSwitchesInOpenflowDomain(sw);
77 assertEquals(expectedCluster.length, cluster.size());
78 for (long sw2: cluster) {
79 assertTrue(Arrays.binarySearch(expectedCluster, (int)sw2) >= 0);
80 verifiedSwitches.add(sw2);
81 }
82 }
83 }
84 }
85 }
86
87 protected void
88 verifyExpectedBroadcastPortsInClusters(int [][][] ebp) {
89 verifyExpectedBroadcastPortsInClusters(ebp, true);
90 }
91
92 protected void
93 verifyExpectedBroadcastPortsInClusters(int [][][] ebp,
94 boolean tunnelsEnabled) {
95 NodePortTuple npt = null;
96 Set<NodePortTuple> expected = new HashSet<NodePortTuple>();
97 for(int i=0; i<ebp.length; ++i) {
98 int [][] nptList = ebp[i];
99 expected.clear();
100 for(int j=0; j<nptList.length; ++j) {
101 npt = new NodePortTuple((long)nptList[j][0], (short)nptList[j][1]);
102 expected.add(npt);
103 }
104 TopologyInstance ti = topologyManager.getCurrentInstance(tunnelsEnabled);
105 Set<NodePortTuple> computed = ti.getBroadcastNodePortsInCluster(npt.nodeId);
106 if (computed != null)
107 assertTrue(computed.equals(expected));
108 else if (computed == null)
109 assertTrue(expected.isEmpty());
110 }
111 }
112
113 public void createTopologyFromLinks(int [][] linkArray) throws Exception {
114 ILinkDiscovery.LinkType type = ILinkDiscovery.LinkType.DIRECT_LINK;
115
116 // Use topologymanager to write this test, it will make it a lot easier.
117 for (int i = 0; i < linkArray.length; i++) {
118 int [] r = linkArray[i];
119 if (r[4] == DIRECT_LINK)
120 type= ILinkDiscovery.LinkType.DIRECT_LINK;
121 else if (r[4] == MULTIHOP_LINK)
122 type= ILinkDiscovery.LinkType.MULTIHOP_LINK;
123 else if (r[4] == TUNNEL_LINK)
124 type = ILinkDiscovery.LinkType.TUNNEL;
125
126 topologyManager.addOrUpdateLink((long)r[0], (short)r[1], (long)r[2], (short)r[3], type);
127 }
128 topologyManager.createNewInstance();
129 }
130
131 public TopologyManager getTopologyManager() {
132 return topologyManager;
133 }
134
135 @Test
136 public void testClusters() throws Exception {
137 TopologyManager tm = getTopologyManager();
138 {
139 int [][] linkArray = {
140 {1, 1, 2, 1, DIRECT_LINK},
141 {2, 2, 3, 2, DIRECT_LINK},
142 {3, 1, 1, 2, DIRECT_LINK},
143 {2, 3, 4, 2, DIRECT_LINK},
144 {3, 3, 4, 1, DIRECT_LINK}
145 };
146 int [][] expectedClusters = {
147 {1,2,3},
148 {4}
149 };
150 //tm.recompute();
151 createTopologyFromLinks(linkArray);
152 verifyClusters(expectedClusters);
153 }
154
155 {
156 int [][] linkArray = {
157 {5, 3, 6, 1, DIRECT_LINK}
158 };
159 int [][] expectedClusters = {
160 {1,2,3},
161 {4},
162 {5},
163 {6}
164 };
165 createTopologyFromLinks(linkArray);
166
167 verifyClusters(expectedClusters);
168 }
169
170 {
171 int [][] linkArray = {
172 {6, 1, 5, 3, DIRECT_LINK}
173 };
174 int [][] expectedClusters = {
175 {1,2,3},
176 {4},
177 {5,6}
178 };
179 createTopologyFromLinks(linkArray);
180
181 verifyClusters(expectedClusters);
182 }
183
184 {
185 int [][] linkArray = {
186 {4, 2, 2, 3, DIRECT_LINK}
187 };
188 int [][] expectedClusters = {
189 {1,2,3,4},
190 {5,6}
191 };
192 createTopologyFromLinks(linkArray);
193
194 verifyClusters(expectedClusters);
195 }
196 {
197 int [][] linkArray = {
198 {4, 3, 5, 1, DIRECT_LINK}
199 };
200 int [][] expectedClusters = {
201 {1,2,3,4},
202 {5,6}
203 };
204 createTopologyFromLinks(linkArray);
205
206 verifyClusters(expectedClusters);
207 }
208 {
209 int [][] linkArray = {
210 {5, 2, 2, 4, DIRECT_LINK}
211 };
212 int [][] expectedClusters = {
213 {1,2,3,4,5,6}
214 };
215 createTopologyFromLinks(linkArray);
216
217 verifyClusters(expectedClusters);
218 }
219
220 //Test 2.
221 {
222 int [][] linkArray = {
223 {3, 2, 2, 2, DIRECT_LINK},
224 {2, 1, 1, 1, DIRECT_LINK},
225 {1, 2, 3, 1, DIRECT_LINK},
226 {4, 1, 3, 3, DIRECT_LINK},
227 {5, 1, 4, 3, DIRECT_LINK},
228 {2, 4, 5, 2, DIRECT_LINK}
229 };
230 int [][] expectedClusters = {
231 {1,2,3,4,5,6}
232 };
233 createTopologyFromLinks(linkArray);
234 verifyClusters(expectedClusters);
235 }
236
237 // Test 3. Remove links
238 {
239 tm.removeLink((long)5,(short)3,(long)6,(short)1);
240 tm.removeLink((long)6,(short)1,(long)5,(short)3);
241
242 int [][] expectedClusters = {
243 {1,2,3,4,5},
244 };
245 topologyManager.createNewInstance();
246 verifyClusters(expectedClusters);
247 }
248
249 // Remove Switch
250 {
251 tm.removeSwitch(4);
252 int [][] expectedClusters = {
253 {1,2,3,5},
254 };
255 topologyManager.createNewInstance();
256 verifyClusters(expectedClusters);
257 }
258 }
259
260 @Test
261 public void testLoopDetectionInSingleIsland() throws Exception {
262
263 int [][] linkArray = {
264 {1, 1, 2, 1, DIRECT_LINK},
265 {2, 1, 1, 1, DIRECT_LINK},
266 {1, 2, 3, 1, DIRECT_LINK},
267 {3, 1, 1, 2, DIRECT_LINK},
268 {2, 2, 3, 2, DIRECT_LINK},
269 {3, 2, 2, 2, DIRECT_LINK},
270 {3, 3, 4, 1, DIRECT_LINK},
271 {4, 1, 3, 3, DIRECT_LINK},
272 {4, 2, 6, 2, DIRECT_LINK},
273 {6, 2, 4, 2, DIRECT_LINK},
274 {4, 3, 5, 1, DIRECT_LINK},
275 {5, 1, 4, 3, DIRECT_LINK},
276 {5, 2, 6, 1, DIRECT_LINK},
277 {6, 1, 5, 2, DIRECT_LINK},
278
279 };
280 int [][] expectedClusters = {
281 {1, 2, 3, 4, 5, 6}
282 };
283 int [][][] expectedBroadcastPorts = {
284 {{1,1}, {2,1}, {1,2}, {3,1}, {3,3}, {4,1}, {4,3}, {5,1}, {4,2}, {6,2}},
285 };
286
287 createTopologyFromLinks(linkArray);
288 topologyManager.createNewInstance();
289 verifyClusters(expectedClusters);
290 verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts);
291 }
292
293 @Test
294 public void testTunnelLinkDeletion() throws Exception {
295
296 // +-------+ +-------+
297 // | | | |
298 // | 1 1|-------------|1 2 |
299 // | 2 | | 2 |
300 // +-------+ +-------+
301 // | |
302 // | |
303 // +-------+ |
304 // | 1 | |
305 // | 3 2|-----------------+
306 // | 3 |
307 // +-------+
308 //
309 //
310 // +-------+
311 // | 1 |
312 // | 4 2|----------------+
313 // | 3 | |
314 // +-------+ |
315 // | |
316 // | |
317 // +-------+ +-------+
318 // | 1 | | 2 |
319 // | 5 2|-------------|1 6 |
320 // | | | |
321 // +-------+ +-------+
322 {
323 int [][] linkArray = {
324 {1, 1, 2, 1, DIRECT_LINK},
325 {2, 1, 1, 1, DIRECT_LINK},
326 {1, 2, 3, 1, TUNNEL_LINK},
327 {3, 1, 1, 2, TUNNEL_LINK},
328 {2, 2, 3, 2, TUNNEL_LINK},
329 {3, 2, 2, 2, TUNNEL_LINK},
330
331 {4, 2, 6, 2, DIRECT_LINK},
332 {6, 2, 4, 2, DIRECT_LINK},
333 {4, 3, 5, 1, TUNNEL_LINK},
334 {5, 1, 4, 3, TUNNEL_LINK},
335 {5, 2, 6, 1, TUNNEL_LINK},
336 {6, 1, 5, 2, TUNNEL_LINK},
337
338 };
339
340 int [][] expectedClusters = {
341 {1, 2},
342 {4, 6},
343 };
344 int [][][] expectedBroadcastPorts = {
345 {{1,1}, {2,1}},
346 {{4,2}, {6,2}}
347 };
348
349 createTopologyFromLinks(linkArray);
350 topologyManager.createNewInstance();
351 verifyClusters(expectedClusters, false);
352 verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts, false);
353 }
354
355 // +-------+ +-------+
356 // | | TUNNEL | |
357 // | 1 1|-------------|1 2 |
358 // | 2 | | 2 |
359 // +-------+ +-------+
360 // | |
361 // | |
362 // +-------+ |
363 // | 1 | |
364 // | 3 2|-----------------+
365 // | 3 |
366 // +-------+
367 // |
368 // | TUNNEL
369 // |
370 // +-------+
371 // | 1 | TUNNEL
372 // | 4 2|----------------+
373 // | 3 | |
374 // +-------+ |
375 // | |
376 // | |
377 // +-------+ +-------+
378 // | 1 | | 2 |
379 // | 5 2|-------------|1 6 |
380 // | | | |
381 // +-------+ +-------+
382
383 {
384 int [][] linkArray = {
385 {3, 3, 4, 1, TUNNEL_LINK},
386 {4, 1, 3, 3, TUNNEL_LINK},
387
388 };
389 int [][] expectedClusters = {
390 {1, 2},
391 {4, 6},
392 {3},
393 {5},
394 };
395 int [][][] expectedBroadcastPorts = {
396 {{1,1}, {2,1}},
397 {{4,2}, {6,2}}
398 };
399
400 createTopologyFromLinks(linkArray);
401 topologyManager.createNewInstance();
402 verifyClusters(expectedClusters, false);
403 verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts, false);
404 }
405 }
406
407 @Test
408 public void testLoopDetectionWithIslands() throws Exception {
409
410 // +-------+ +-------+
411 // | | TUNNEL | |
412 // | 1 1|-------------|1 2 |
413 // | 2 | | 2 |
414 // +-------+ +-------+
415 // | |
416 // | |
417 // +-------+ |
418 // | 1 | |
419 // | 3 2|-----------------+
420 // | 3 |
421 // +-------+
422 //
423 //
424 // +-------+
425 // | 1 | TUNNEL
426 // | 4 2|----------------+
427 // | 3 | |
428 // +-------+ |
429 // | |
430 // | |
431 // +-------+ +-------+
432 // | 1 | | 2 |
433 // | 5 2|-------------|1 6 |
434 // | | | |
435 // +-------+ +-------+
436 {
437 int [][] linkArray = {
438 {1, 1, 2, 1, TUNNEL_LINK},
439 {2, 1, 1, 1, TUNNEL_LINK},
440 {1, 2, 3, 1, DIRECT_LINK},
441 {3, 1, 1, 2, DIRECT_LINK},
442 {2, 2, 3, 2, DIRECT_LINK},
443 {3, 2, 2, 2, DIRECT_LINK},
444
445 {4, 2, 6, 2, TUNNEL_LINK},
446 {6, 2, 4, 2, TUNNEL_LINK},
447 {4, 3, 5, 1, DIRECT_LINK},
448 {5, 1, 4, 3, DIRECT_LINK},
449 {5, 2, 6, 1, DIRECT_LINK},
450 {6, 1, 5, 2, DIRECT_LINK},
451
452 };
453
454 int [][] expectedClusters = {
455 {1, 2, 3},
456 {4, 5, 6}
457 };
458 int [][][] expectedBroadcastPorts = {
459 {{1,2}, {3,1}, {2,2}, {3,2}},
460 {{4,3}, {5,1}, {5,2}, {6,1}},
461 };
462
463 createTopologyFromLinks(linkArray);
464 topologyManager.createNewInstance();
465 verifyClusters(expectedClusters);
466 verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts);
467 }
468
469 // +-------+ +-------+
470 // | | TUNNEL | |
471 // | 1 1|-------------|1 2 |
472 // | 2 | | 2 |
473 // +-------+ +-------+
474 // | |
475 // | |
476 // +-------+ |
477 // | 1 | |
478 // | 3 2|-----------------+
479 // | 3 |
480 // +-------+
481 // |
482 // | TUNNEL
483 // |
484 // +-------+
485 // | 1 | TUNNEL
486 // | 4 2|----------------+
487 // | 3 | |
488 // +-------+ |
489 // | |
490 // | |
491 // +-------+ +-------+
492 // | 1 | | 2 |
493 // | 5 2|-------------|1 6 |
494 // | | | |
495 // +-------+ +-------+
496
497 {
498 int [][] linkArray = {
499 {3, 3, 4, 1, TUNNEL_LINK},
500 {4, 1, 3, 3, TUNNEL_LINK},
501
502 };
503 int [][] expectedClusters = {
504 {1, 2, 3},
505 {4, 5, 6}
506 };
507 int [][][] expectedBroadcastPorts = {
508 {{1,2}, {3,1}, {2,2}, {3,2}},
509 {{4,3}, {5,1}, {5,2}, {6,1}},
510 };
511
512 createTopologyFromLinks(linkArray);
513 topologyManager.createNewInstance();
514 verifyClusters(expectedClusters, false);
515 verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts);
516 }
517 }
518}