blob: af29d763fe64a22252bdbe0d41df0d8057b02ce4 [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 HIGUCHI44a0b352014-05-14 21:32:48 -070055 protected static final 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
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070083 @Override
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080084 @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(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700118 System.currentTimeMillis(), null,
119 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800120 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(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700142 System.currentTimeMillis(), null,
143 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800144 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(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700164 System.currentTimeMillis(), null,
165 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800166 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(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700187 System.currentTimeMillis(), null,
188 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800189 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(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700208 System.currentTimeMillis(), null,
209 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800210 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(),
Ray Milkey269ffb92014-04-03 14:43:30 -0700233 System.currentTimeMillis(), null,
234 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800235 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);
Ray Milkey269ffb92014-04-03 14:43:30 -0700255
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800256 LinkInfo info;
257
258 info = new LinkInfo(System.currentTimeMillis() - 40000,
Ray Milkey269ffb92014-04-03 14:43:30 -0700259 System.currentTimeMillis() - 40000, null,
260 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800261 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 ||
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700272 !topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800273 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700274 !topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800275
276 topology.timeoutLinks();
277
278
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700279 info = new LinkInfo(System.currentTimeMillis(), /* firstseen */
280 null, /* unicast */
Ray Milkey269ffb92014-04-03 14:43:30 -0700281 System.currentTimeMillis(), 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800282 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,
Ray Milkey269ffb92014-04-03 14:43:30 -0700295 System.currentTimeMillis() - 40000, null, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800296 topology.addOrUpdateLink(lt, info);
297 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700298 !topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800299 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700300 !topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800301
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,
Ray Milkey269ffb92014-04-03 14:43:30 -0700312 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800313 topology.addOrUpdateLink(lt, info);
314 topology.timeoutLinks();
315 assertTrue(topology.links.get(lt) == null);
316 assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700317 !topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800318 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700319 !topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800320
321
322 // Test again only with multicast LLDP
323 info = new LinkInfo(System.currentTimeMillis() - 40000,
Ray Milkey269ffb92014-04-03 14:43:30 -0700324 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800325 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 ||
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700335 !topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800336 assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700337 !topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800338
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,
Ray Milkey269ffb92014-04-03 14:43:30 -0700344 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800345 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,
Ray Milkey269ffb92014-04-03 14:43:30 -0700355 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800356 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,
Ray Milkey269ffb92014-04-03 14:43:30 -0700366 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800367 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,
Ray Milkey269ffb92014-04-03 14:43:30 -0700377 null, System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800378 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}