blob: c6d114312a1337f3a2130292925f4dd9e22f9649 [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;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080036import net.floodlightcontroller.test.FloodlightTestCase;
37import net.floodlightcontroller.threadpool.IThreadPoolService;
HIGUCHI Yutaa56fbde2013-06-17 14:26:05 -070038import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
39import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
Jonathan Hart02a59e42014-03-26 18:50:23 -070040import net.onrc.onos.ofcontroller.linkdiscovery.Link;
HIGUCHI Yutaa56fbde2013-06-17 14:26:05 -070041import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
Jonathan Hart02a59e42014-03-26 18:50:23 -070042import net.onrc.onos.ofcontroller.linkdiscovery.NodePortTuple;
Jonathan Hart2fa28062013-11-25 20:16:28 -080043
44import org.junit.Before;
45import org.junit.Test;
46import org.slf4j.Logger;
47import org.slf4j.LoggerFactory;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080048
49/**
50 *
51 * @author David Erickson (daviderickson@cs.stanford.edu)
52 */
53public class LinkDiscoveryManagerTest extends FloodlightTestCase {
54
55 private TestLinkDiscoveryManager ldm;
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070056 protected final static Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080057
58 public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
59 public boolean isSendLLDPsCalled = false;
60 public boolean isClearLinksCalled = false;
61
62 @Override
63 protected void discoverOnAllPorts() {
64 isSendLLDPsCalled = true;
65 super.discoverOnAllPorts();
66 }
67
68 public void reset() {
69 isSendLLDPsCalled = false;
70 isClearLinksCalled = false;
71 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080072 }
73
74 public LinkDiscoveryManager getTopology() {
75 return ldm;
76 }
77
78 public IOFSwitch createMockSwitch(Long id) {
79 IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
80 expect(mockSwitch.getId()).andReturn(id).anyTimes();
81 return mockSwitch;
82 }
83
84 @Before
85 public void setUp() throws Exception {
86 super.setUp();
87 FloodlightModuleContext cntx = new FloodlightModuleContext();
88 ldm = new TestLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080089 ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
90 MockThreadPoolService tp = new MockThreadPoolService();
91 RestApiServer restApi = new RestApiServer();
92 cntx.addService(IRestApiService.class, restApi);
93 cntx.addService(IThreadPoolService.class, tp);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080094 cntx.addService(ILinkDiscoveryService.class, ldm);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080095 cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
96 restApi.init(cntx);
97 tp.init(cntx);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080098 ldm.init(cntx);
99 restApi.startUp(cntx);
100 tp.startUp(cntx);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800101 ldm.startUp(cntx);
102
103 IOFSwitch sw1 = createMockSwitch(1L);
104 IOFSwitch sw2 = createMockSwitch(2L);
105 Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
106 switches.put(1L, sw1);
107 switches.put(2L, sw2);
108 getMockFloodlightProvider().setSwitches(switches);
109 replay(sw1, sw2);
110 }
111
112 @Test
113 public void testAddOrUpdateLink() throws Exception {
114 LinkDiscoveryManager topology = getTopology();
115
116 Link lt = new Link(1L, 2, 2L, 1);
117 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
118 System.currentTimeMillis(), null,
119 0, 0);
120 topology.addOrUpdateLink(lt, info);
121
122
123 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
124 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
125
126 // check invariants hold
127 assertNotNull(topology.switchLinks.get(lt.getSrc()));
128 assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
129 assertNotNull(topology.portLinks.get(srcNpt));
130 assertTrue(topology.portLinks.get(srcNpt).contains(lt));
131 assertNotNull(topology.portLinks.get(dstNpt));
132 assertTrue(topology.portLinks.get(dstNpt).contains(lt));
133 assertTrue(topology.links.containsKey(lt));
134 }
135
136 @Test
137 public void testDeleteLink() throws Exception {
138 LinkDiscoveryManager topology = getTopology();
139
140 Link lt = new Link(1L, 2, 2L, 1);
141 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
142 System.currentTimeMillis(), null,
143 0, 0);
144 topology.addOrUpdateLink(lt, info);
145 topology.deleteLinks(Collections.singletonList(lt), "Test");
146
147 // check invariants hold
148 assertNull(topology.switchLinks.get(lt.getSrc()));
149 assertNull(topology.switchLinks.get(lt.getDst()));
150 assertNull(topology.portLinks.get(lt.getSrc()));
151 assertNull(topology.portLinks.get(lt.getDst()));
152 assertTrue(topology.links.isEmpty());
153 }
154
155 @Test
156 public void testAddOrUpdateLinkToSelf() throws Exception {
157 LinkDiscoveryManager topology = getTopology();
158
159 Link lt = new Link(1L, 2, 2L, 3);
160 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
161 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
162
163 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
164 System.currentTimeMillis(), null,
165 0, 0);
166 topology.addOrUpdateLink(lt, info);
167
168 // check invariants hold
169 assertNotNull(topology.switchLinks.get(lt.getSrc()));
170 assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
171 assertNotNull(topology.portLinks.get(srcNpt));
172 assertTrue(topology.portLinks.get(srcNpt).contains(lt));
173 assertNotNull(topology.portLinks.get(dstNpt));
174 assertTrue(topology.portLinks.get(dstNpt).contains(lt));
175 assertTrue(topology.links.containsKey(lt));
176 }
177
178 @Test
179 public void testDeleteLinkToSelf() throws Exception {
180 LinkDiscoveryManager topology = getTopology();
181
182 Link lt = new Link(1L, 2, 1L, 3);
183 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
184 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
185
186 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
187 System.currentTimeMillis(), null,
188 0, 0);
189 topology.addOrUpdateLink(lt, info);
190 topology.deleteLinks(Collections.singletonList(lt), "Test to self");
191
192 // check invariants hold
193 assertNull(topology.switchLinks.get(lt.getSrc()));
194 assertNull(topology.switchLinks.get(lt.getDst()));
195 assertNull(topology.portLinks.get(srcNpt));
196 assertNull(topology.portLinks.get(dstNpt));
197 assertTrue(topology.links.isEmpty());
198 }
199
200 @Test
201 public void testRemovedSwitch() {
202 LinkDiscoveryManager topology = getTopology();
203
204 Link lt = new Link(1L, 2, 2L, 1);
205 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
206 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
207 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
208 System.currentTimeMillis(), null,
209 0, 0);
210 topology.addOrUpdateLink(lt, info);
211
212 IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
213 IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
214 // Mock up our expected behavior
215 topology.removedSwitch(sw1);
216 verify(sw1, sw2);
217
218 // check invariants hold
219 assertNull(topology.switchLinks.get(lt.getSrc()));
220 assertNull(topology.switchLinks.get(lt.getDst()));
221 assertNull(topology.portLinks.get(srcNpt));
222 assertNull(topology.portLinks.get(dstNpt));
223 assertTrue(topology.links.isEmpty());
224 }
225
226 @Test
227 public void testRemovedSwitchSelf() {
228 LinkDiscoveryManager topology = getTopology();
229 IOFSwitch sw1 = createMockSwitch(1L);
230 replay(sw1);
231 Link lt = new Link(1L, 2, 1L, 3);
232 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
233 System.currentTimeMillis(), null,
234 0, 0);
235 topology.addOrUpdateLink(lt, info);
236
237 // Mock up our expected behavior
238 topology.removedSwitch(sw1);
239
240 verify(sw1);
241 // check invariants hold
242 assertNull(topology.switchLinks.get(lt.getSrc()));
243 assertNull(topology.portLinks.get(lt.getSrc()));
244 assertNull(topology.portLinks.get(lt.getDst()));
245 assertTrue(topology.links.isEmpty());
246 }
247
248 @Test
249 public void testAddUpdateLinks() throws Exception {
250 LinkDiscoveryManager topology = getTopology();
251
252 Link lt = new Link(1L, 1, 2L, 1);
253 NodePortTuple srcNpt = new NodePortTuple(1L, 1);
254 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
255
256 LinkInfo info;
257
258 info = new LinkInfo(System.currentTimeMillis() - 40000,
259 System.currentTimeMillis() - 40000, null,
260 0, 0);
261 topology.addOrUpdateLink(lt, info);
262
263 // check invariants hold
264 assertNotNull(topology.switchLinks.get(lt.getSrc()));
265 assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
266 assertNotNull(topology.portLinks.get(srcNpt));
267 assertTrue(topology.portLinks.get(srcNpt).contains(lt));
268 assertNotNull(topology.portLinks.get(dstNpt));
269 assertTrue(topology.portLinks.get(dstNpt).contains(lt));
270 assertTrue(topology.links.containsKey(lt));
271 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
272 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
273 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
274 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
275
276 topology.timeoutLinks();
277
278
279 info = new LinkInfo(System.currentTimeMillis(),/* firstseen */
280 null,/* unicast */
281 System.currentTimeMillis(), 0, 0);
282 topology.addOrUpdateLink(lt, info);
283 assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
284 assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
285 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
286 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
287
288
289 // Add a link info based on info that woudld be obtained from unicast LLDP
290 // Setting the unicast LLDP reception time to be 40 seconds old, so we can use
291 // this to test timeout after this test. Although the info is initialized
292 // with LT_OPENFLOW_LINK, the link property should be changed to LT_NON_OPENFLOW
293 // by the addOrUpdateLink method.
294 info = new LinkInfo(System.currentTimeMillis() - 40000,
295 System.currentTimeMillis() - 40000, null, 0, 0);
296 topology.addOrUpdateLink(lt, info);
297 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
298 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
299 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
300 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
301
302 // Expect to timeout the unicast Valid Time, but not the multicast Valid time
303 // So the link type should go back to non-openflow link.
304 topology.timeoutLinks();
305 assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
306 assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
307 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
308 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
309
310 // Set the multicastValidTime to be old and see if that also times out.
311 info = new LinkInfo(System.currentTimeMillis() - 40000,
312 null, System.currentTimeMillis() - 40000, 0, 0);
313 topology.addOrUpdateLink(lt, info);
314 topology.timeoutLinks();
315 assertTrue(topology.links.get(lt) == null);
316 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
317 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
318 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
319 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
320
321
322 // Test again only with multicast LLDP
323 info = new LinkInfo(System.currentTimeMillis() - 40000,
324 null, System.currentTimeMillis() - 40000, 0, 0);
325 topology.addOrUpdateLink(lt, info);
326 assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
327 assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
328 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
329 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
330
331 // Call timeout and check if link is no longer present.
332 topology.timeoutLinks();
333 assertTrue(topology.links.get(lt) == null);
334 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
335 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
336 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
337 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
338
339 // Start clean and see if loops are also added.
340 lt = new Link(1L, 1, 1L, 2);
341 srcNpt = new NodePortTuple(1L, 1);
342 dstNpt = new NodePortTuple(1L, 2);
343 info = new LinkInfo(System.currentTimeMillis() - 40000,
344 null, System.currentTimeMillis() - 40000, 0, 0);
345 topology.addOrUpdateLink(lt, info);
346 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
347 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
348
349
350 // Start clean and see if loops are also added.
351 lt = new Link(1L, 1, 1L, 3);
352 srcNpt = new NodePortTuple(1L, 1);
353 dstNpt = new NodePortTuple(1L, 3);
354 info = new LinkInfo(System.currentTimeMillis() - 40000,
355 null, System.currentTimeMillis() - 40000, 0, 0);
356 topology.addOrUpdateLink(lt, info);
357 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
358 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
359
360
361 // Start clean and see if loops are also added.
362 lt = new Link(1L, 4, 1L, 5);
363 srcNpt = new NodePortTuple(1L, 4);
364 dstNpt = new NodePortTuple(1L, 5);
365 info = new LinkInfo(System.currentTimeMillis() - 40000,
366 null, System.currentTimeMillis() - 40000, 0, 0);
367 topology.addOrUpdateLink(lt, info);
368 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
369 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
370
371
372 // Start clean and see if loops are also added.
373 lt = new Link(1L, 3, 1L, 5);
374 srcNpt = new NodePortTuple(1L, 3);
375 dstNpt = new NodePortTuple(1L, 5);
376 info = new LinkInfo(System.currentTimeMillis() - 40000,
377 null, System.currentTimeMillis() - 40000, 0, 0);
378 topology.addOrUpdateLink(lt, info);
379 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
380 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
381 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800382}