blob: da9d30b1da4b2096bd2e63c4e4c3d7fda18bff71 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
Ray Milkey269ffb92014-04-03 14:43:30 -07002 * 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 **/
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080017
Jonathan Hart23701d12014-04-03 10:45:48 -070018package net.onrc.onos.core.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;
Jonathan Hart23701d12014-04-03 10:45:48 -070038import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryListener;
39import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
40import net.onrc.onos.core.linkdiscovery.Link;
41import net.onrc.onos.core.linkdiscovery.LinkInfo;
42import net.onrc.onos.core.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/**
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080050 * @author David Erickson (daviderickson@cs.stanford.edu)
51 */
52public class LinkDiscoveryManagerTest extends FloodlightTestCase {
53
54 private TestLinkDiscoveryManager ldm;
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070055 protected final static Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
Ray Milkey269ffb92014-04-03 14:43:30 -070056
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080057 public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
58 public boolean isSendLLDPsCalled = false;
59 public boolean isClearLinksCalled = false;
60
61 @Override
62 protected void discoverOnAllPorts() {
63 isSendLLDPsCalled = true;
64 super.discoverOnAllPorts();
65 }
66
67 public void reset() {
68 isSendLLDPsCalled = false;
69 isClearLinksCalled = false;
70 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080071 }
Ray Milkey269ffb92014-04-03 14:43:30 -070072
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080073 public LinkDiscoveryManager getTopology() {
74 return ldm;
75 }
76
77 public IOFSwitch createMockSwitch(Long id) {
78 IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
79 expect(mockSwitch.getId()).andReturn(id).anyTimes();
80 return mockSwitch;
81 }
82
83 @Before
84 public void setUp() throws Exception {
85 super.setUp();
86 FloodlightModuleContext cntx = new FloodlightModuleContext();
87 ldm = new TestLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080088 ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
89 MockThreadPoolService tp = new MockThreadPoolService();
90 RestApiServer restApi = new RestApiServer();
91 cntx.addService(IRestApiService.class, restApi);
92 cntx.addService(IThreadPoolService.class, tp);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080093 cntx.addService(ILinkDiscoveryService.class, ldm);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080094 cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
95 restApi.init(cntx);
96 tp.init(cntx);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080097 ldm.init(cntx);
98 restApi.startUp(cntx);
99 tp.startUp(cntx);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800100 ldm.startUp(cntx);
101
102 IOFSwitch sw1 = createMockSwitch(1L);
103 IOFSwitch sw2 = createMockSwitch(2L);
104 Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
105 switches.put(1L, sw1);
106 switches.put(2L, sw2);
107 getMockFloodlightProvider().setSwitches(switches);
108 replay(sw1, sw2);
109 }
110
111 @Test
112 public void testAddOrUpdateLink() throws Exception {
113 LinkDiscoveryManager topology = getTopology();
114
115 Link lt = new Link(1L, 2, 2L, 1);
116 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700117 System.currentTimeMillis(), null,
118 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800119 topology.addOrUpdateLink(lt, info);
120
121
122 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
123 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
124
125 // check invariants hold
126 assertNotNull(topology.switchLinks.get(lt.getSrc()));
127 assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
128 assertNotNull(topology.portLinks.get(srcNpt));
129 assertTrue(topology.portLinks.get(srcNpt).contains(lt));
130 assertNotNull(topology.portLinks.get(dstNpt));
131 assertTrue(topology.portLinks.get(dstNpt).contains(lt));
132 assertTrue(topology.links.containsKey(lt));
133 }
134
135 @Test
136 public void testDeleteLink() throws Exception {
137 LinkDiscoveryManager topology = getTopology();
138
139 Link lt = new Link(1L, 2, 2L, 1);
140 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700141 System.currentTimeMillis(), null,
142 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800143 topology.addOrUpdateLink(lt, info);
144 topology.deleteLinks(Collections.singletonList(lt), "Test");
145
146 // check invariants hold
147 assertNull(topology.switchLinks.get(lt.getSrc()));
148 assertNull(topology.switchLinks.get(lt.getDst()));
149 assertNull(topology.portLinks.get(lt.getSrc()));
150 assertNull(topology.portLinks.get(lt.getDst()));
151 assertTrue(topology.links.isEmpty());
152 }
153
154 @Test
155 public void testAddOrUpdateLinkToSelf() throws Exception {
156 LinkDiscoveryManager topology = getTopology();
157
158 Link lt = new Link(1L, 2, 2L, 3);
159 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
160 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
161
162 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700163 System.currentTimeMillis(), null,
164 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800165 topology.addOrUpdateLink(lt, info);
166
167 // check invariants hold
168 assertNotNull(topology.switchLinks.get(lt.getSrc()));
169 assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
170 assertNotNull(topology.portLinks.get(srcNpt));
171 assertTrue(topology.portLinks.get(srcNpt).contains(lt));
172 assertNotNull(topology.portLinks.get(dstNpt));
173 assertTrue(topology.portLinks.get(dstNpt).contains(lt));
174 assertTrue(topology.links.containsKey(lt));
175 }
176
177 @Test
178 public void testDeleteLinkToSelf() throws Exception {
179 LinkDiscoveryManager topology = getTopology();
180
181 Link lt = new Link(1L, 2, 1L, 3);
182 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
183 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
184
185 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700186 System.currentTimeMillis(), null,
187 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800188 topology.addOrUpdateLink(lt, info);
189 topology.deleteLinks(Collections.singletonList(lt), "Test to self");
190
191 // check invariants hold
192 assertNull(topology.switchLinks.get(lt.getSrc()));
193 assertNull(topology.switchLinks.get(lt.getDst()));
194 assertNull(topology.portLinks.get(srcNpt));
195 assertNull(topology.portLinks.get(dstNpt));
196 assertTrue(topology.links.isEmpty());
197 }
198
199 @Test
200 public void testRemovedSwitch() {
201 LinkDiscoveryManager topology = getTopology();
202
203 Link lt = new Link(1L, 2, 2L, 1);
204 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
205 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
206 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700207 System.currentTimeMillis(), null,
208 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800209 topology.addOrUpdateLink(lt, info);
210
211 IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
212 IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
213 // Mock up our expected behavior
214 topology.removedSwitch(sw1);
215 verify(sw1, sw2);
216
217 // check invariants hold
218 assertNull(topology.switchLinks.get(lt.getSrc()));
219 assertNull(topology.switchLinks.get(lt.getDst()));
220 assertNull(topology.portLinks.get(srcNpt));
221 assertNull(topology.portLinks.get(dstNpt));
222 assertTrue(topology.links.isEmpty());
223 }
224
225 @Test
226 public void testRemovedSwitchSelf() {
227 LinkDiscoveryManager topology = getTopology();
228 IOFSwitch sw1 = createMockSwitch(1L);
229 replay(sw1);
230 Link lt = new Link(1L, 2, 1L, 3);
231 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700232 System.currentTimeMillis(), null,
233 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800234 topology.addOrUpdateLink(lt, info);
235
236 // Mock up our expected behavior
237 topology.removedSwitch(sw1);
238
239 verify(sw1);
240 // check invariants hold
241 assertNull(topology.switchLinks.get(lt.getSrc()));
242 assertNull(topology.portLinks.get(lt.getSrc()));
243 assertNull(topology.portLinks.get(lt.getDst()));
244 assertTrue(topology.links.isEmpty());
245 }
246
247 @Test
248 public void testAddUpdateLinks() throws Exception {
249 LinkDiscoveryManager topology = getTopology();
250
251 Link lt = new Link(1L, 1, 2L, 1);
252 NodePortTuple srcNpt = new NodePortTuple(1L, 1);
253 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
Ray Milkey269ffb92014-04-03 14:43:30 -0700254
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800255 LinkInfo info;
256
257 info = new LinkInfo(System.currentTimeMillis() - 40000,
Ray Milkey269ffb92014-04-03 14:43:30 -0700258 System.currentTimeMillis() - 40000, null,
259 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800260 topology.addOrUpdateLink(lt, info);
261
262 // check invariants hold
263 assertNotNull(topology.switchLinks.get(lt.getSrc()));
264 assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
265 assertNotNull(topology.portLinks.get(srcNpt));
266 assertTrue(topology.portLinks.get(srcNpt).contains(lt));
267 assertNotNull(topology.portLinks.get(dstNpt));
268 assertTrue(topology.portLinks.get(dstNpt).contains(lt));
269 assertTrue(topology.links.containsKey(lt));
270 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
271 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
272 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
273 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
274
275 topology.timeoutLinks();
276
277
278 info = new LinkInfo(System.currentTimeMillis(),/* firstseen */
Ray Milkey269ffb92014-04-03 14:43:30 -0700279 null,/* unicast */
280 System.currentTimeMillis(), 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800281 topology.addOrUpdateLink(lt, info);
282 assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
283 assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
284 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
285 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
286
287
288 // Add a link info based on info that woudld be obtained from unicast LLDP
289 // Setting the unicast LLDP reception time to be 40 seconds old, so we can use
290 // this to test timeout after this test. Although the info is initialized
291 // with LT_OPENFLOW_LINK, the link property should be changed to LT_NON_OPENFLOW
292 // by the addOrUpdateLink method.
293 info = new LinkInfo(System.currentTimeMillis() - 40000,
Ray Milkey269ffb92014-04-03 14:43:30 -0700294 System.currentTimeMillis() - 40000, null, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800295 topology.addOrUpdateLink(lt, info);
296 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
297 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
298 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
299 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
300
301 // Expect to timeout the unicast Valid Time, but not the multicast Valid time
302 // So the link type should go back to non-openflow link.
303 topology.timeoutLinks();
304 assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
305 assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
306 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
307 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
308
309 // Set the multicastValidTime to be old and see if that also times out.
310 info = new LinkInfo(System.currentTimeMillis() - 40000,
Ray Milkey269ffb92014-04-03 14:43:30 -0700311 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800312 topology.addOrUpdateLink(lt, info);
313 topology.timeoutLinks();
314 assertTrue(topology.links.get(lt) == null);
315 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
316 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
317 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
318 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
319
320
321 // Test again only with multicast LLDP
322 info = new LinkInfo(System.currentTimeMillis() - 40000,
Ray Milkey269ffb92014-04-03 14:43:30 -0700323 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800324 topology.addOrUpdateLink(lt, info);
325 assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
326 assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
327 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
328 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
329
330 // Call timeout and check if link is no longer present.
331 topology.timeoutLinks();
332 assertTrue(topology.links.get(lt) == null);
333 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
334 topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
335 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
336 topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
337
338 // Start clean and see if loops are also added.
339 lt = new Link(1L, 1, 1L, 2);
340 srcNpt = new NodePortTuple(1L, 1);
341 dstNpt = new NodePortTuple(1L, 2);
342 info = new LinkInfo(System.currentTimeMillis() - 40000,
Ray Milkey269ffb92014-04-03 14:43:30 -0700343 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800344 topology.addOrUpdateLink(lt, info);
345 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
346 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
347
348
349 // Start clean and see if loops are also added.
350 lt = new Link(1L, 1, 1L, 3);
351 srcNpt = new NodePortTuple(1L, 1);
352 dstNpt = new NodePortTuple(1L, 3);
353 info = new LinkInfo(System.currentTimeMillis() - 40000,
Ray Milkey269ffb92014-04-03 14:43:30 -0700354 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800355 topology.addOrUpdateLink(lt, info);
356 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
357 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
358
359
360 // Start clean and see if loops are also added.
361 lt = new Link(1L, 4, 1L, 5);
362 srcNpt = new NodePortTuple(1L, 4);
363 dstNpt = new NodePortTuple(1L, 5);
364 info = new LinkInfo(System.currentTimeMillis() - 40000,
Ray Milkey269ffb92014-04-03 14:43:30 -0700365 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800366 topology.addOrUpdateLink(lt, info);
367 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
368 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
369
370
371 // Start clean and see if loops are also added.
372 lt = new Link(1L, 3, 1L, 5);
373 srcNpt = new NodePortTuple(1L, 3);
374 dstNpt = new NodePortTuple(1L, 5);
375 info = new LinkInfo(System.currentTimeMillis() - 40000,
Ray Milkey269ffb92014-04-03 14:43:30 -0700376 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800377 topology.addOrUpdateLink(lt, info);
378 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
379 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
380 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800381}