blob: dd748acca68272c455662091cd74eb74aadae5ff [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
srikanth9f383342014-06-12 11:49:00 -070025import java.io.IOException;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080026import java.util.ArrayList;
Jonathan Hart2fa28062013-11-25 20:16:28 -080027import java.util.Collections;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080028import java.util.HashMap;
29import java.util.Map;
30
srikanth9f383342014-06-12 11:49:00 -070031import net.floodlightcontroller.core.FloodlightContext;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080032import net.floodlightcontroller.core.IFloodlightProviderService;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080033import net.floodlightcontroller.core.IOFSwitch;
34import net.floodlightcontroller.core.module.FloodlightModuleContext;
35import net.floodlightcontroller.core.test.MockThreadPoolService;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080036import net.floodlightcontroller.restserver.IRestApiService;
37import net.floodlightcontroller.restserver.RestApiServer;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080038import net.floodlightcontroller.test.FloodlightTestCase;
39import net.floodlightcontroller.threadpool.IThreadPoolService;
Jonathan Hart23701d12014-04-03 10:45:48 -070040import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryListener;
41import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
42import net.onrc.onos.core.linkdiscovery.Link;
43import net.onrc.onos.core.linkdiscovery.LinkInfo;
44import net.onrc.onos.core.linkdiscovery.NodePortTuple;
Jonathan Hart2fa28062013-11-25 20:16:28 -080045
srikanth9f383342014-06-12 11:49:00 -070046import org.easymock.EasyMock;
Jonathan Hart2fa28062013-11-25 20:16:28 -080047import org.junit.Before;
48import org.junit.Test;
srikanth9f383342014-06-12 11:49:00 -070049import org.openflow.protocol.OFMessage;
50import org.openflow.protocol.OFPhysicalPort;
Jonathan Hart2fa28062013-11-25 20:16:28 -080051import org.slf4j.Logger;
52import org.slf4j.LoggerFactory;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080053
Yuta HIGUCHIaa132f52014-06-26 10:18:39 -070054// CHECKSTYLE IGNORE WriteTag FOR NEXT 2 LINES
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080055/**
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080056 * @author David Erickson (daviderickson@cs.stanford.edu)
57 */
58public class LinkDiscoveryManagerTest extends FloodlightTestCase {
59
60 private TestLinkDiscoveryManager ldm;
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070061 protected static final Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
Ray Milkey269ffb92014-04-03 14:43:30 -070062
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080063 public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
64 public boolean isSendLLDPsCalled = false;
65 public boolean isClearLinksCalled = false;
66
67 @Override
68 protected void discoverOnAllPorts() {
69 isSendLLDPsCalled = true;
70 super.discoverOnAllPorts();
71 }
72
73 public void reset() {
74 isSendLLDPsCalled = false;
75 isClearLinksCalled = false;
76 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080077 }
Ray Milkey269ffb92014-04-03 14:43:30 -070078
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080079 public LinkDiscoveryManager getTopology() {
80 return ldm;
81 }
82
83 public IOFSwitch createMockSwitch(Long id) {
84 IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
85 expect(mockSwitch.getId()).andReturn(id).anyTimes();
86 return mockSwitch;
87 }
88
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070089 @Override
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080090 @Before
91 public void setUp() throws Exception {
92 super.setUp();
93 FloodlightModuleContext cntx = new FloodlightModuleContext();
94 ldm = new TestLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080095 ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
96 MockThreadPoolService tp = new MockThreadPoolService();
97 RestApiServer restApi = new RestApiServer();
98 cntx.addService(IRestApiService.class, restApi);
99 cntx.addService(IThreadPoolService.class, tp);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800100 cntx.addService(ILinkDiscoveryService.class, ldm);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800101 cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
102 restApi.init(cntx);
103 tp.init(cntx);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800104 ldm.init(cntx);
105 restApi.startUp(cntx);
106 tp.startUp(cntx);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800107 ldm.startUp(cntx);
108
109 IOFSwitch sw1 = createMockSwitch(1L);
110 IOFSwitch sw2 = createMockSwitch(2L);
111 Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
112 switches.put(1L, sw1);
113 switches.put(2L, sw2);
114 getMockFloodlightProvider().setSwitches(switches);
115 replay(sw1, sw2);
116 }
117
118 @Test
119 public void testAddOrUpdateLink() throws Exception {
120 LinkDiscoveryManager topology = getTopology();
121
122 Link lt = new Link(1L, 2, 2L, 1);
123 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Jonathan Hartba354e02014-06-30 19:18:16 -0700124 System.currentTimeMillis(), 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800125 topology.addOrUpdateLink(lt, info);
126
127
128 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
129 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
130
131 // check invariants hold
132 assertNotNull(topology.switchLinks.get(lt.getSrc()));
133 assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
134 assertNotNull(topology.portLinks.get(srcNpt));
135 assertTrue(topology.portLinks.get(srcNpt).contains(lt));
136 assertNotNull(topology.portLinks.get(dstNpt));
137 assertTrue(topology.portLinks.get(dstNpt).contains(lt));
138 assertTrue(topology.links.containsKey(lt));
139 }
140
141 @Test
142 public void testDeleteLink() throws Exception {
143 LinkDiscoveryManager topology = getTopology();
144
145 Link lt = new Link(1L, 2, 2L, 1);
146 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Jonathan Hartba354e02014-06-30 19:18:16 -0700147 System.currentTimeMillis(), 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800148 topology.addOrUpdateLink(lt, info);
149 topology.deleteLinks(Collections.singletonList(lt), "Test");
150
151 // check invariants hold
152 assertNull(topology.switchLinks.get(lt.getSrc()));
153 assertNull(topology.switchLinks.get(lt.getDst()));
154 assertNull(topology.portLinks.get(lt.getSrc()));
155 assertNull(topology.portLinks.get(lt.getDst()));
156 assertTrue(topology.links.isEmpty());
157 }
158
159 @Test
160 public void testAddOrUpdateLinkToSelf() throws Exception {
161 LinkDiscoveryManager topology = getTopology();
162
163 Link lt = new Link(1L, 2, 2L, 3);
164 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
165 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
166
167 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Jonathan Hartba354e02014-06-30 19:18:16 -0700168 System.currentTimeMillis(), 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800169 topology.addOrUpdateLink(lt, info);
170
171 // check invariants hold
172 assertNotNull(topology.switchLinks.get(lt.getSrc()));
173 assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
174 assertNotNull(topology.portLinks.get(srcNpt));
175 assertTrue(topology.portLinks.get(srcNpt).contains(lt));
176 assertNotNull(topology.portLinks.get(dstNpt));
177 assertTrue(topology.portLinks.get(dstNpt).contains(lt));
178 assertTrue(topology.links.containsKey(lt));
179 }
180
181 @Test
182 public void testDeleteLinkToSelf() throws Exception {
183 LinkDiscoveryManager topology = getTopology();
184
185 Link lt = new Link(1L, 2, 1L, 3);
186 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
187 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
188
189 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Jonathan Hartba354e02014-06-30 19:18:16 -0700190 System.currentTimeMillis(), 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800191 topology.addOrUpdateLink(lt, info);
192 topology.deleteLinks(Collections.singletonList(lt), "Test to self");
193
194 // check invariants hold
195 assertNull(topology.switchLinks.get(lt.getSrc()));
196 assertNull(topology.switchLinks.get(lt.getDst()));
197 assertNull(topology.portLinks.get(srcNpt));
198 assertNull(topology.portLinks.get(dstNpt));
199 assertTrue(topology.links.isEmpty());
200 }
201
202 @Test
203 public void testRemovedSwitch() {
204 LinkDiscoveryManager topology = getTopology();
205
206 Link lt = new Link(1L, 2, 2L, 1);
207 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
208 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
209 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Jonathan Hartba354e02014-06-30 19:18:16 -0700210 System.currentTimeMillis(), 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800211 topology.addOrUpdateLink(lt, info);
212
213 IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
214 IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
215 // Mock up our expected behavior
216 topology.removedSwitch(sw1);
217 verify(sw1, sw2);
218
219 // check invariants hold
220 assertNull(topology.switchLinks.get(lt.getSrc()));
221 assertNull(topology.switchLinks.get(lt.getDst()));
222 assertNull(topology.portLinks.get(srcNpt));
223 assertNull(topology.portLinks.get(dstNpt));
224 assertTrue(topology.links.isEmpty());
225 }
226
227 @Test
228 public void testRemovedSwitchSelf() {
229 LinkDiscoveryManager topology = getTopology();
230 IOFSwitch sw1 = createMockSwitch(1L);
231 replay(sw1);
232 Link lt = new Link(1L, 2, 1L, 3);
233 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Jonathan Hartba354e02014-06-30 19:18:16 -0700234 System.currentTimeMillis(), 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,
Jonathan Hartba354e02014-06-30 19:18:16 -0700259 System.currentTimeMillis() - 40000, 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));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800270
271 topology.timeoutLinks();
272
273
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700274 info = new LinkInfo(System.currentTimeMillis(), /* firstseen */
Jonathan Hartba354e02014-06-30 19:18:16 -0700275 null, /* unicast */0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800276 topology.addOrUpdateLink(lt, info);
277 assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800278
279
Jonathan Hartba354e02014-06-30 19:18:16 -0700280 // Add a link info based on info that would be obtained from unicast LLDP
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800281 // Setting the unicast LLDP reception time to be 40 seconds old, so we can use
282 // this to test timeout after this test. Although the info is initialized
283 // with LT_OPENFLOW_LINK, the link property should be changed to LT_NON_OPENFLOW
284 // by the addOrUpdateLink method.
285 info = new LinkInfo(System.currentTimeMillis() - 40000,
Jonathan Hartba354e02014-06-30 19:18:16 -0700286 System.currentTimeMillis() - 40000, 0, 0);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800287 topology.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800288
289 // Expect to timeout the unicast Valid Time, but not the multicast Valid time
290 // So the link type should go back to non-openflow link.
291 topology.timeoutLinks();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800292 assertTrue(topology.links.get(lt) == null);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800293 }
srikanth9f383342014-06-12 11:49:00 -0700294
295 /**
296 * This test case verifies that LinkDiscoveryManager.sendDiscoveryMessage()
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700297 * performs "write" operation on the specified IOFSwitch object
298 * with a LLDP packet.
299 *
srikanth9f383342014-06-12 11:49:00 -0700300 * @throws IOException
301 */
302 @Test
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700303 public void testSendDiscoveryMessage() throws IOException {
Jonathan Hart299d1132014-06-27 09:25:28 -0700304 byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
305
srikanth9f383342014-06-12 11:49:00 -0700306 LinkDiscoveryManager topology = getTopology();
307
308 // Mock up our expected behavior
309 IOFSwitch swTest = createMockSwitch(3L);
310 getMockFloodlightProvider().getSwitches().put(3L, swTest);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700311
srikanth9f383342014-06-12 11:49:00 -0700312 short portNum = 1;
313 OFPhysicalPort ofpPort = new OFPhysicalPort();
314 ofpPort.setPortNumber(portNum);
Jonathan Hart299d1132014-06-27 09:25:28 -0700315 ofpPort.setHardwareAddress(macAddress);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700316
317 /* sendDiscoverMessage() should perform the following actions on
srikanth9f383342014-06-12 11:49:00 -0700318 * IOFSwitch object
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700319 * - getPort() with argument as "1"
320 * - write() with OFPacketOut
321 * - flush()
srikanth9f383342014-06-12 11:49:00 -0700322 */
323 expect(swTest.getPort(portNum)).andReturn(ofpPort).atLeastOnce();
324 swTest.write(EasyMock.anyObject(OFMessage.class), EasyMock.anyObject(FloodlightContext.class));
325 EasyMock.expectLastCall().times(1);
326 swTest.flush();
327 EasyMock.expectLastCall().once();
328 replay(swTest);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700329
Jonathan Hartba354e02014-06-30 19:18:16 -0700330 topology.sendDiscoveryMessage(3L, portNum, false);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700331
srikanth9f383342014-06-12 11:49:00 -0700332 verify(swTest);
333 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800334}