blob: ecb87cf60783c2f95d340c54e1c65f0387087e9b [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
2* Copyright 2011, Big Switch Networks, Inc.
3* Originally created by David Erickson, Stanford University
4*
5* Licensed under the Apache License, Version 2.0 (the "License"); you may
6* not use this file except in compliance with the License. You may obtain
7* a copy of the License at
8*
9* http://www.apache.org/licenses/LICENSE-2.0
10*
11* Unless required by applicable law or agreed to in writing, software
12* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14* License for the specific language governing permissions and limitations
15* under the License.
16**/
17
HIGUCHI Yutaa56fbde2013-06-17 14:26:05 -070018package net.onrc.onos.ofcontroller.linkdiscovery.internal;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080019
Jonathan Hart2fa28062013-11-25 20:16:28 -080020import static org.easymock.EasyMock.createNiceMock;
21import static org.easymock.EasyMock.expect;
22import static org.easymock.EasyMock.replay;
23import static org.easymock.EasyMock.verify;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080024
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080025import java.util.ArrayList;
Jonathan Hart2fa28062013-11-25 20:16:28 -080026import java.util.Collections;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080027import java.util.HashMap;
28import java.util.Map;
29
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080030import net.floodlightcontroller.core.IFloodlightProviderService;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080031import net.floodlightcontroller.core.IOFSwitch;
32import net.floodlightcontroller.core.module.FloodlightModuleContext;
33import net.floodlightcontroller.core.test.MockThreadPoolService;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080034import net.floodlightcontroller.restserver.IRestApiService;
35import net.floodlightcontroller.restserver.RestApiServer;
36import net.floodlightcontroller.routing.IRoutingService;
37import net.floodlightcontroller.routing.Link;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080038import net.floodlightcontroller.test.FloodlightTestCase;
39import net.floodlightcontroller.threadpool.IThreadPoolService;
40import net.floodlightcontroller.topology.ITopologyService;
41import net.floodlightcontroller.topology.NodePortTuple;
42import net.floodlightcontroller.topology.TopologyManager;
HIGUCHI Yutaa56fbde2013-06-17 14:26:05 -070043import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
44import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
45import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
Jonathan Hart2fa28062013-11-25 20:16:28 -080046
47import org.junit.Before;
48import org.junit.Test;
49import org.slf4j.Logger;
50import org.slf4j.LoggerFactory;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080051
52/**
53 *
54 * @author David Erickson (daviderickson@cs.stanford.edu)
55 */
56public class LinkDiscoveryManagerTest extends FloodlightTestCase {
57
58 private TestLinkDiscoveryManager ldm;
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070059 protected final static Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080060
61 public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
62 public boolean isSendLLDPsCalled = false;
63 public boolean isClearLinksCalled = false;
64
65 @Override
66 protected void discoverOnAllPorts() {
67 isSendLLDPsCalled = true;
68 super.discoverOnAllPorts();
69 }
70
71 public void reset() {
72 isSendLLDPsCalled = false;
73 isClearLinksCalled = false;
74 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080075 }
76
77 public LinkDiscoveryManager getTopology() {
78 return ldm;
79 }
80
81 public IOFSwitch createMockSwitch(Long id) {
82 IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
83 expect(mockSwitch.getId()).andReturn(id).anyTimes();
84 return mockSwitch;
85 }
86
87 @Before
88 public void setUp() throws Exception {
89 super.setUp();
90 FloodlightModuleContext cntx = new FloodlightModuleContext();
91 ldm = new TestLinkDiscoveryManager();
92 TopologyManager routingEngine = new TopologyManager();
93 ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
94 MockThreadPoolService tp = new MockThreadPoolService();
95 RestApiServer restApi = new RestApiServer();
96 cntx.addService(IRestApiService.class, restApi);
97 cntx.addService(IThreadPoolService.class, tp);
98 cntx.addService(IRoutingService.class, routingEngine);
99 cntx.addService(ILinkDiscoveryService.class, ldm);
100 cntx.addService(ITopologyService.class, ldm);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800101 cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
102 restApi.init(cntx);
103 tp.init(cntx);
104 routingEngine.init(cntx);
105 ldm.init(cntx);
106 restApi.startUp(cntx);
107 tp.startUp(cntx);
108 routingEngine.startUp(cntx);
109 ldm.startUp(cntx);
110
111 IOFSwitch sw1 = createMockSwitch(1L);
112 IOFSwitch sw2 = createMockSwitch(2L);
113 Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
114 switches.put(1L, sw1);
115 switches.put(2L, sw2);
116 getMockFloodlightProvider().setSwitches(switches);
117 replay(sw1, sw2);
118 }
119
120 @Test
121 public void testAddOrUpdateLink() throws Exception {
122 LinkDiscoveryManager topology = getTopology();
123
124 Link lt = new Link(1L, 2, 2L, 1);
125 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
126 System.currentTimeMillis(), null,
127 0, 0);
128 topology.addOrUpdateLink(lt, info);
129
130
131 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
132 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
133
134 // check invariants hold
135 assertNotNull(topology.switchLinks.get(lt.getSrc()));
136 assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
137 assertNotNull(topology.portLinks.get(srcNpt));
138 assertTrue(topology.portLinks.get(srcNpt).contains(lt));
139 assertNotNull(topology.portLinks.get(dstNpt));
140 assertTrue(topology.portLinks.get(dstNpt).contains(lt));
141 assertTrue(topology.links.containsKey(lt));
142 }
143
144 @Test
145 public void testDeleteLink() throws Exception {
146 LinkDiscoveryManager topology = getTopology();
147
148 Link lt = new Link(1L, 2, 2L, 1);
149 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
150 System.currentTimeMillis(), null,
151 0, 0);
152 topology.addOrUpdateLink(lt, info);
153 topology.deleteLinks(Collections.singletonList(lt), "Test");
154
155 // check invariants hold
156 assertNull(topology.switchLinks.get(lt.getSrc()));
157 assertNull(topology.switchLinks.get(lt.getDst()));
158 assertNull(topology.portLinks.get(lt.getSrc()));
159 assertNull(topology.portLinks.get(lt.getDst()));
160 assertTrue(topology.links.isEmpty());
161 }
162
163 @Test
164 public void testAddOrUpdateLinkToSelf() throws Exception {
165 LinkDiscoveryManager topology = getTopology();
166
167 Link lt = new Link(1L, 2, 2L, 3);
168 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
169 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
170
171 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
172 System.currentTimeMillis(), null,
173 0, 0);
174 topology.addOrUpdateLink(lt, info);
175
176 // check invariants hold
177 assertNotNull(topology.switchLinks.get(lt.getSrc()));
178 assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
179 assertNotNull(topology.portLinks.get(srcNpt));
180 assertTrue(topology.portLinks.get(srcNpt).contains(lt));
181 assertNotNull(topology.portLinks.get(dstNpt));
182 assertTrue(topology.portLinks.get(dstNpt).contains(lt));
183 assertTrue(topology.links.containsKey(lt));
184 }
185
186 @Test
187 public void testDeleteLinkToSelf() throws Exception {
188 LinkDiscoveryManager topology = getTopology();
189
190 Link lt = new Link(1L, 2, 1L, 3);
191 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
192 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
193
194 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
195 System.currentTimeMillis(), null,
196 0, 0);
197 topology.addOrUpdateLink(lt, info);
198 topology.deleteLinks(Collections.singletonList(lt), "Test to self");
199
200 // check invariants hold
201 assertNull(topology.switchLinks.get(lt.getSrc()));
202 assertNull(topology.switchLinks.get(lt.getDst()));
203 assertNull(topology.portLinks.get(srcNpt));
204 assertNull(topology.portLinks.get(dstNpt));
205 assertTrue(topology.links.isEmpty());
206 }
207
208 @Test
209 public void testRemovedSwitch() {
210 LinkDiscoveryManager topology = getTopology();
211
212 Link lt = new Link(1L, 2, 2L, 1);
213 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
214 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
215 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
216 System.currentTimeMillis(), null,
217 0, 0);
218 topology.addOrUpdateLink(lt, info);
219
220 IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
221 IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
222 // Mock up our expected behavior
223 topology.removedSwitch(sw1);
224 verify(sw1, sw2);
225
226 // check invariants hold
227 assertNull(topology.switchLinks.get(lt.getSrc()));
228 assertNull(topology.switchLinks.get(lt.getDst()));
229 assertNull(topology.portLinks.get(srcNpt));
230 assertNull(topology.portLinks.get(dstNpt));
231 assertTrue(topology.links.isEmpty());
232 }
233
234 @Test
235 public void testRemovedSwitchSelf() {
236 LinkDiscoveryManager topology = getTopology();
237 IOFSwitch sw1 = createMockSwitch(1L);
238 replay(sw1);
239 Link lt = new Link(1L, 2, 1L, 3);
240 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
241 System.currentTimeMillis(), null,
242 0, 0);
243 topology.addOrUpdateLink(lt, info);
244
245 // Mock up our expected behavior
246 topology.removedSwitch(sw1);
247
248 verify(sw1);
249 // check invariants hold
250 assertNull(topology.switchLinks.get(lt.getSrc()));
251 assertNull(topology.portLinks.get(lt.getSrc()));
252 assertNull(topology.portLinks.get(lt.getDst()));
253 assertTrue(topology.links.isEmpty());
254 }
255
256 @Test
257 public void testAddUpdateLinks() throws Exception {
258 LinkDiscoveryManager topology = getTopology();
259
260 Link lt = new Link(1L, 1, 2L, 1);
261 NodePortTuple srcNpt = new NodePortTuple(1L, 1);
262 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
263
264 LinkInfo info;
265
266 info = new LinkInfo(System.currentTimeMillis() - 40000,
267 System.currentTimeMillis() - 40000, null,
268 0, 0);
269 topology.addOrUpdateLink(lt, info);
270
271 // check invariants hold
272 assertNotNull(topology.switchLinks.get(lt.getSrc()));
273 assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
274 assertNotNull(topology.portLinks.get(srcNpt));
275 assertTrue(topology.portLinks.get(srcNpt).contains(lt));
276 assertNotNull(topology.portLinks.get(dstNpt));
277 assertTrue(topology.portLinks.get(dstNpt).contains(lt));
278 assertTrue(topology.links.containsKey(lt));
279 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
280 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
281 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
282 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
283
284 topology.timeoutLinks();
285
286
287 info = new LinkInfo(System.currentTimeMillis(),/* firstseen */
288 null,/* unicast */
289 System.currentTimeMillis(), 0, 0);
290 topology.addOrUpdateLink(lt, info);
291 assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
292 assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
293 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
294 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
295
296
297 // Add a link info based on info that woudld be obtained from unicast LLDP
298 // Setting the unicast LLDP reception time to be 40 seconds old, so we can use
299 // this to test timeout after this test. Although the info is initialized
300 // with LT_OPENFLOW_LINK, the link property should be changed to LT_NON_OPENFLOW
301 // by the addOrUpdateLink method.
302 info = new LinkInfo(System.currentTimeMillis() - 40000,
303 System.currentTimeMillis() - 40000, null, 0, 0);
304 topology.addOrUpdateLink(lt, info);
305 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
306 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
307 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
308 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
309
310 // Expect to timeout the unicast Valid Time, but not the multicast Valid time
311 // So the link type should go back to non-openflow link.
312 topology.timeoutLinks();
313 assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
314 assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
315 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
316 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
317
318 // Set the multicastValidTime to be old and see if that also times out.
319 info = new LinkInfo(System.currentTimeMillis() - 40000,
320 null, System.currentTimeMillis() - 40000, 0, 0);
321 topology.addOrUpdateLink(lt, info);
322 topology.timeoutLinks();
323 assertTrue(topology.links.get(lt) == null);
324 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
325 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
326 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
327 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
328
329
330 // Test again only with multicast LLDP
331 info = new LinkInfo(System.currentTimeMillis() - 40000,
332 null, System.currentTimeMillis() - 40000, 0, 0);
333 topology.addOrUpdateLink(lt, info);
334 assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
335 assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
336 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
337 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
338
339 // Call timeout and check if link is no longer present.
340 topology.timeoutLinks();
341 assertTrue(topology.links.get(lt) == null);
342 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
343 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
344 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
345 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
346
347 // Start clean and see if loops are also added.
348 lt = new Link(1L, 1, 1L, 2);
349 srcNpt = new NodePortTuple(1L, 1);
350 dstNpt = new NodePortTuple(1L, 2);
351 info = new LinkInfo(System.currentTimeMillis() - 40000,
352 null, System.currentTimeMillis() - 40000, 0, 0);
353 topology.addOrUpdateLink(lt, info);
354 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
355 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
356
357
358 // Start clean and see if loops are also added.
359 lt = new Link(1L, 1, 1L, 3);
360 srcNpt = new NodePortTuple(1L, 1);
361 dstNpt = new NodePortTuple(1L, 3);
362 info = new LinkInfo(System.currentTimeMillis() - 40000,
363 null, System.currentTimeMillis() - 40000, 0, 0);
364 topology.addOrUpdateLink(lt, info);
365 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
366 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
367
368
369 // Start clean and see if loops are also added.
370 lt = new Link(1L, 4, 1L, 5);
371 srcNpt = new NodePortTuple(1L, 4);
372 dstNpt = new NodePortTuple(1L, 5);
373 info = new LinkInfo(System.currentTimeMillis() - 40000,
374 null, System.currentTimeMillis() - 40000, 0, 0);
375 topology.addOrUpdateLink(lt, info);
376 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
377 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
378
379
380 // Start clean and see if loops are also added.
381 lt = new Link(1L, 3, 1L, 5);
382 srcNpt = new NodePortTuple(1L, 3);
383 dstNpt = new NodePortTuple(1L, 5);
384 info = new LinkInfo(System.currentTimeMillis() - 40000,
385 null, System.currentTimeMillis() - 40000, 0, 0);
386 topology.addOrUpdateLink(lt, info);
387 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
388 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
389 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800390}