blob: 8c63293e41a5a9cfe512e9753efcb165e45e8afd [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 Hart284e70f2014-07-05 12:32:51 -070018package net.onrc.onos.core.linkdiscovery;
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;
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;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070029import java.util.Set;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080030
srikanth9f383342014-06-12 11:49:00 -070031import net.floodlightcontroller.core.FloodlightContext;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080032import net.floodlightcontroller.core.IFloodlightProviderService;
Jonathan Hart0f383542014-07-09 11:38:03 -070033import net.floodlightcontroller.core.IListener.Command;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080034import net.floodlightcontroller.core.IOFSwitch;
35import net.floodlightcontroller.core.module.FloodlightModuleContext;
36import net.floodlightcontroller.core.test.MockThreadPoolService;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080037import net.floodlightcontroller.restserver.IRestApiService;
38import net.floodlightcontroller.restserver.RestApiServer;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080039import net.floodlightcontroller.test.FloodlightTestCase;
40import net.floodlightcontroller.threadpool.IThreadPoolService;
Jonathan Hart0f383542014-07-09 11:38:03 -070041import net.onrc.onos.core.packet.Ethernet;
42import net.onrc.onos.core.packet.OnosLldp;
Jonathan Hartcd1ab172014-07-03 14:59:48 -070043import net.onrc.onos.core.registry.IControllerRegistryService;
Jonathan Hart2fa28062013-11-25 20:16:28 -080044
srikanth9f383342014-06-12 11:49:00 -070045import org.easymock.EasyMock;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070046import org.easymock.IArgumentMatcher;
Jonathan Hart2fa28062013-11-25 20:16:28 -080047import org.junit.Before;
48import org.junit.Test;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070049import org.projectfloodlight.openflow.protocol.OFFactories;
50import org.projectfloodlight.openflow.protocol.OFFactory;
51import org.projectfloodlight.openflow.protocol.OFPacketIn;
52import org.projectfloodlight.openflow.protocol.OFPacketOut;
53import org.projectfloodlight.openflow.protocol.OFPortConfig;
54import org.projectfloodlight.openflow.protocol.OFPortDesc;
55import org.projectfloodlight.openflow.protocol.OFPortReason;
56import org.projectfloodlight.openflow.protocol.OFPortState;
57import org.projectfloodlight.openflow.protocol.OFPortStatus;
58import org.projectfloodlight.openflow.protocol.OFVersion;
59import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
60import org.projectfloodlight.openflow.types.MacAddress;
61import org.projectfloodlight.openflow.types.OFPort;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080062
Yuta HIGUCHIaa132f52014-06-26 10:18:39 -070063// CHECKSTYLE IGNORE WriteTag FOR NEXT 2 LINES
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080064/**
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080065 * @author David Erickson (daviderickson@cs.stanford.edu)
66 */
67public class LinkDiscoveryManagerTest extends FloodlightTestCase {
68
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070069 private LinkDiscoveryManager ldm;
Ray Milkey269ffb92014-04-03 14:43:30 -070070
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070071 private static final Set<OFPortState> EMPTY_PORT_STATE =
72 Collections.<OFPortState>emptySet();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080073
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070074 // Arbitrary MAC address that we can feed in to our mock objects. This
75 // value is never actually checked during the tests so it doesn't matter if
76 // all ports have the same MAC address.
77 private static final byte[] DEFAULT_MAC_ADDRESS =
78 new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
79
80 private OFFactory factory10 = OFFactories.getFactory(OFVersion.OF_10);
81
82 /**
83 * EasyMock matcher to verify the value of the output port of a packet out.
84 * This is used to verify that the packet out messages generated by
85 * LinkDiscoveryManager contain the correct output port.
86 *
87 */
88 private static final class PacketOutPortMatcher implements IArgumentMatcher {
89 private final int portNumber;
90
91 public PacketOutPortMatcher(int portNumber) {
92 this.portNumber = portNumber;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080093 }
94
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070095 @Override
96 public void appendTo(StringBuffer strBuffer) {
97 strBuffer.append("PacketOutPortMatcher failed to verify output port");
98 }
99
100 @Override
101 public boolean matches(Object object) {
102 if (!(object instanceof OFPacketOut)) {
103 return false;
104 }
105
106 OFPacketOut po = (OFPacketOut) object;
107
108 if (po.getActions().size() != 1
109 || !(po.getActions().get(0) instanceof OFActionOutput)) {
110 return false;
111 }
112
113 OFActionOutput action = (OFActionOutput) po.getActions().get(0);
114
115 return action.getPort().getPortNumber() == portNumber;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800116 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800117 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700118
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700119 /**
120 * Matcher method to match a given output port against a packet out message
121 * passed as an argument to a mock switch.
122 *
123 * @param outPort the output port to check in the packet out
124 * @return anything of type OFPacketOut
125 */
126 private static OFPacketOut matchOutPort(int outPort) {
127 EasyMock.reportMatcher(new PacketOutPortMatcher(outPort));
128 return null;
129 }
130
131 private LinkDiscoveryManager getLinkDiscoveryManager() {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800132 return ldm;
133 }
134
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700135 private IOFSwitch createMockSwitch(Long id) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800136 IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
137 expect(mockSwitch.getId()).andReturn(id).anyTimes();
Jonathan Hart0f383542014-07-09 11:38:03 -0700138 expect(mockSwitch.portEnabled(EasyMock.anyShort())).andReturn(true).anyTimes();
Jonathan Harta213bce2014-08-11 15:44:07 -0700139 expect(mockSwitch.getFactory()).andReturn(factory10).anyTimes();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800140 return mockSwitch;
141 }
142
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700143 private OFPortDesc createMockPort(short portNumber) {
144 return createMockPortWithState(portNumber,
145 Collections.<OFPortState>emptySet());
146 }
147
148 private OFPortDesc createMockPortWithState(short portNumber,
149 Set<OFPortState> state) {
150 OFPort ofPort = EasyMock.createMock(OFPort.class);
151 expect(ofPort.getShortPortNumber()).andReturn(portNumber).anyTimes();
152
153 OFPortDesc ofPortDesc = EasyMock.createMock(OFPortDesc.class);
154 expect(ofPortDesc.getPortNo()).andReturn(ofPort).anyTimes();
155 expect(ofPortDesc.getHwAddr()).andReturn(
156 MacAddress.of(DEFAULT_MAC_ADDRESS)).anyTimes();
157 expect(ofPortDesc.getConfig()).
158 andReturn(Collections.<OFPortConfig>emptySet()).anyTimes();
159 expect(ofPortDesc.getState()).andReturn(state).anyTimes();
160
161 replay(ofPort);
162 replay(ofPortDesc);
163
164 return ofPortDesc;
165 }
166
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700167 @Override
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800168 @Before
169 public void setUp() throws Exception {
170 super.setUp();
171 FloodlightModuleContext cntx = new FloodlightModuleContext();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700172 ldm = new LinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800173 MockThreadPoolService tp = new MockThreadPoolService();
174 RestApiServer restApi = new RestApiServer();
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700175 IControllerRegistryService registry =
176 EasyMock.createMock(IControllerRegistryService.class);
177 expect(registry.hasControl(EasyMock.anyLong())).andReturn(true).anyTimes();
178 replay(registry);
179 cntx.addService(IControllerRegistryService.class, registry);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800180 cntx.addService(IRestApiService.class, restApi);
181 cntx.addService(IThreadPoolService.class, tp);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800182 cntx.addService(ILinkDiscoveryService.class, ldm);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800183 cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
184 restApi.init(cntx);
185 tp.init(cntx);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800186 ldm.init(cntx);
187 restApi.startUp(cntx);
188 tp.startUp(cntx);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800189 ldm.startUp(cntx);
190
191 IOFSwitch sw1 = createMockSwitch(1L);
192 IOFSwitch sw2 = createMockSwitch(2L);
193 Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
194 switches.put(1L, sw1);
195 switches.put(2L, sw2);
196 getMockFloodlightProvider().setSwitches(switches);
197 replay(sw1, sw2);
198 }
199
200 @Test
201 public void testAddOrUpdateLink() throws Exception {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700202 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800203
204 Link lt = new Link(1L, 2, 2L, 1);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700205 long firstSeenTime = System.currentTimeMillis();
206 LinkInfo info = new LinkInfo(firstSeenTime,
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700207 System.currentTimeMillis(), EMPTY_PORT_STATE,
208 EMPTY_PORT_STATE);
209 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800210
211 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
212 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
213
214 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700215 assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
216 assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
217 assertNotNull(linkDiscovery.portLinks.get(srcNpt));
218 assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
219 assertNotNull(linkDiscovery.portLinks.get(dstNpt));
220 assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
221 assertTrue(linkDiscovery.links.containsKey(lt));
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700222
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700223 LinkInfo infoToVerify = linkDiscovery.links.get(lt);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700224 assertEquals(firstSeenTime, infoToVerify.getFirstSeenTime());
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700225 assertEquals(EMPTY_PORT_STATE, infoToVerify.getSrcPortState());
226 assertEquals(EMPTY_PORT_STATE, infoToVerify.getDstPortState());
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700227
228 // Arbitrary new port states to verify that the port state is updated
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700229 final Set<OFPortState> newSrcPortState =
230 Collections.singleton(OFPortState.STP_BLOCK);
231 final Set<OFPortState> newDstPortState =
232 Collections.singleton(OFPortState.LINK_DOWN);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700233
234 // Update the last received probe timestamp and the port states
235 LinkInfo infoWithStateChange = new LinkInfo(System.currentTimeMillis(),
236 System.currentTimeMillis(), newSrcPortState, newDstPortState);
237
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700238 linkDiscovery.addOrUpdateLink(lt, infoWithStateChange);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700239
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700240 assertNotNull(linkDiscovery.links.get(lt));
241 infoToVerify = linkDiscovery.links.get(lt);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700242 // First seen time should be the original time, not the second update time
243 assertEquals(firstSeenTime, infoToVerify.getFirstSeenTime());
244 // Both port states should have been updated
245 assertEquals(newSrcPortState, infoToVerify.getSrcPortState());
246 assertEquals(newDstPortState, infoToVerify.getDstPortState());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800247 }
248
249 @Test
250 public void testDeleteLink() throws Exception {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700251 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800252
253 Link lt = new Link(1L, 2, 2L, 1);
254 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700255 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
256 linkDiscovery.addOrUpdateLink(lt, info);
257 linkDiscovery.deleteLinks(Collections.singletonList(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800258
259 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700260 assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
261 assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
262 assertNull(linkDiscovery.portLinks.get(lt.getSrc()));
263 assertNull(linkDiscovery.portLinks.get(lt.getDst()));
264 assertTrue(linkDiscovery.links.isEmpty());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800265 }
266
267 @Test
268 public void testAddOrUpdateLinkToSelf() throws Exception {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700269 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800270
271 Link lt = new Link(1L, 2, 2L, 3);
272 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
273 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
274
275 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700276 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
277 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800278
279 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700280 assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
281 assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
282 assertNotNull(linkDiscovery.portLinks.get(srcNpt));
283 assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
284 assertNotNull(linkDiscovery.portLinks.get(dstNpt));
285 assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
286 assertTrue(linkDiscovery.links.containsKey(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800287 }
288
289 @Test
290 public void testDeleteLinkToSelf() throws Exception {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700291 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800292
293 Link lt = new Link(1L, 2, 1L, 3);
294 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
295 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
296
297 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700298 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
299 linkDiscovery.addOrUpdateLink(lt, info);
300 linkDiscovery.deleteLinks(Collections.singletonList(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800301
302 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700303 assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
304 assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
305 assertNull(linkDiscovery.portLinks.get(srcNpt));
306 assertNull(linkDiscovery.portLinks.get(dstNpt));
307 assertTrue(linkDiscovery.links.isEmpty());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800308 }
309
310 @Test
311 public void testRemovedSwitch() {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700312 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800313
314 Link lt = new Link(1L, 2, 2L, 1);
315 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
316 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
317 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700318 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
319 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800320
321 IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
322 IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
323 // Mock up our expected behavior
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700324 linkDiscovery.switchDisconnected(sw1.getId());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800325 verify(sw1, sw2);
326
327 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700328 assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
329 assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
330 assertNull(linkDiscovery.portLinks.get(srcNpt));
331 assertNull(linkDiscovery.portLinks.get(dstNpt));
332 assertTrue(linkDiscovery.links.isEmpty());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800333 }
334
335 @Test
336 public void testRemovedSwitchSelf() {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700337 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800338 IOFSwitch sw1 = createMockSwitch(1L);
339 replay(sw1);
340 Link lt = new Link(1L, 2, 1L, 3);
341 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700342 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
343 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800344
345 // Mock up our expected behavior
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700346 linkDiscovery.switchDisconnected(sw1.getId());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800347
348 verify(sw1);
349 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700350 assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
351 assertNull(linkDiscovery.portLinks.get(lt.getSrc()));
352 assertNull(linkDiscovery.portLinks.get(lt.getDst()));
353 assertTrue(linkDiscovery.links.isEmpty());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800354 }
355
356 @Test
357 public void testAddUpdateLinks() throws Exception {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700358 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800359
360 Link lt = new Link(1L, 1, 2L, 1);
361 NodePortTuple srcNpt = new NodePortTuple(1L, 1);
362 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
Ray Milkey269ffb92014-04-03 14:43:30 -0700363
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800364 LinkInfo info;
365
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700366 // Setting the last LLDP reception time to be 40 seconds old, so we
367 // can use this to test that an old link times out correctly
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800368 info = new LinkInfo(System.currentTimeMillis() - 40000,
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700369 System.currentTimeMillis() - 40000,
370 EMPTY_PORT_STATE, EMPTY_PORT_STATE);
371 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800372
373 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700374 assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
375 assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
376 assertNotNull(linkDiscovery.portLinks.get(srcNpt));
377 assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
378 assertNotNull(linkDiscovery.portLinks.get(dstNpt));
379 assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
380 assertTrue(linkDiscovery.links.containsKey(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800381
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700382 linkDiscovery.timeOutLinks();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800383
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700384 // Setting the last LLDP reception time to be 40 seconds old, so we
385 // can use this to test that an old link times out correctly
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800386 info = new LinkInfo(System.currentTimeMillis() - 40000,
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700387 System.currentTimeMillis() - 40000,
388 EMPTY_PORT_STATE, EMPTY_PORT_STATE);
389 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800390
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700391 // Expect to timeout the unicast Valid Time, so the link should disappear
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700392 linkDiscovery.timeOutLinks();
393 assertTrue(linkDiscovery.links.get(lt) == null);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800394 }
srikanth9f383342014-06-12 11:49:00 -0700395
396 /**
397 * This test case verifies that LinkDiscoveryManager.sendDiscoveryMessage()
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700398 * performs "write" operation on the specified IOFSwitch object
399 * with a LLDP packet.
400 *
srikanth9f383342014-06-12 11:49:00 -0700401 * @throws IOException
402 */
403 @Test
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700404 public void testSendDiscoveryMessage() throws IOException {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700405 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
srikanth9f383342014-06-12 11:49:00 -0700406
407 // Mock up our expected behavior
408 IOFSwitch swTest = createMockSwitch(3L);
409 getMockFloodlightProvider().getSwitches().put(3L, swTest);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700410
srikanth9f383342014-06-12 11:49:00 -0700411 short portNum = 1;
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700412
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700413 OFPortDesc ofPortDesc = createMockPort(portNum);
414
415 expect(swTest.getPort(portNum)).andReturn(ofPortDesc).atLeastOnce();
416 swTest.write(matchOutPort(portNum),
417 EasyMock.anyObject(FloodlightContext.class));
srikanth9f383342014-06-12 11:49:00 -0700418 EasyMock.expectLastCall().times(1);
419 swTest.flush();
420 EasyMock.expectLastCall().once();
421 replay(swTest);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700422
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700423 linkDiscovery.sendDiscoveryMessage(3L, portNum, false);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700424
srikanth9f383342014-06-12 11:49:00 -0700425 verify(swTest);
426 }
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700427
428 @Test
429 public void testHandlePortStatusForNewPort() throws IOException {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700430 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700431
432 long dpid = 3L;
433 IOFSwitch sw = createMockSwitch(dpid);
434 getMockFloodlightProvider().getSwitches().put(dpid, sw);
435
436 short portNum = 1;
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700437
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700438 OFPortDesc ofPortDesc = createMockPort(portNum);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700439
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700440 OFPortStatus portStatus = factory10.buildPortStatus()
441 .setDesc(ofPortDesc)
442 .setReason(OFPortReason.ADD)
443 .build();
444
445 expect(sw.getPort(portNum)).andReturn(ofPortDesc).once();
446
447 sw.write(matchOutPort(portNum),
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700448 EasyMock.anyObject(FloodlightContext.class));
449 sw.flush();
450
451 replay(sw);
452
453 linkDiscovery.handlePortStatus(sw, portStatus);
454
455 verify(sw);
456 }
457
458 @Test
459 public void testHandlePortStatusForExistingPort() {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700460 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700461
462 // Add a link that we can update later during the test
463 Link lt = new Link(1L, 1, 2L, 1);
464 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700465 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700466 linkDiscovery.addOrUpdateLink(lt, info);
467
468 short portNum = 1;
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700469
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700470 // Arbitrary states to test state changes
471 Set<OFPortState> srcPortState =
472 Collections.singleton(OFPortState.STP_FORWARD);
473 Set<OFPortState> dstPortState =
474 Collections.singleton(OFPortState.STP_LISTEN);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700475
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700476 OFPortDesc srcPortDesc = createMockPortWithState(portNum, srcPortState);
477 OFPortDesc dstPortDesc = createMockPortWithState(portNum, dstPortState);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700478
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700479 OFPortStatus srcPortStatus = factory10.buildPortStatus()
480 .setDesc(srcPortDesc)
481 .setReason(OFPortReason.MODIFY)
482 .build();
483
484 OFPortStatus dstPortStatus = factory10.buildPortStatus()
485 .setDesc(dstPortDesc)
486 .setReason(OFPortReason.MODIFY)
487 .build();
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700488
489 linkDiscovery.handlePortStatus(
490 getMockFloodlightProvider().getSwitches().get(1L), srcPortStatus);
491
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700492 LinkInfo newInfo = linkDiscovery.links.get(lt);
493 assertEquals(srcPortState, newInfo.getSrcPortState());
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700494 assertEquals(EMPTY_PORT_STATE, newInfo.getDstPortState());
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700495
496 linkDiscovery.handlePortStatus(
497 getMockFloodlightProvider().getSwitches().get(2L), dstPortStatus);
498
499 newInfo = linkDiscovery.links.get(lt);
500 assertEquals(srcPortState, newInfo.getSrcPortState());
501 assertEquals(dstPortState, newInfo.getDstPortState());
502 }
Jonathan Hart0f383542014-07-09 11:38:03 -0700503
504 @Test
505 public void testHandlePortStatusForDeletePort() {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700506 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Jonathan Hart0f383542014-07-09 11:38:03 -0700507
508 // Add a link that we can delete later during the test
509 Link lt = new Link(1L, 1, 2L, 2);
510 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700511 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
Jonathan Hart0f383542014-07-09 11:38:03 -0700512 linkDiscovery.addOrUpdateLink(lt, info);
513
514 short portNum = 1;
Jonathan Hart0f383542014-07-09 11:38:03 -0700515
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700516 OFPortDesc srcPortDesc = createMockPort(portNum);
517 OFPortStatus srcPortStatus = factory10.buildPortStatus()
518 .setDesc(srcPortDesc)
519 .setReason(OFPortReason.DELETE)
520 .build();
Jonathan Hart0f383542014-07-09 11:38:03 -0700521
522 assertNotNull(linkDiscovery.getLinks().get(lt));
523
524 // Send a delete port status for the source port, which should result
525 // in the link being deleted
526 linkDiscovery.handlePortStatus(
527 getMockFloodlightProvider().getSwitches().get(1L), srcPortStatus);
528
529 assertNull(linkDiscovery.getLinks().get(lt));
530 }
531
532 @Test
533 public void testReceive() {
Jonathan Hart0f383542014-07-09 11:38:03 -0700534 OnosLldp lldpPacket = new OnosLldp();
535 lldpPacket.setPort((short) 1);
536 lldpPacket.setSwitch(1L);
537 lldpPacket.setReverse(false);
538
539 Ethernet ethPacket = new Ethernet();
540 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700541 ethPacket.setSourceMACAddress(DEFAULT_MAC_ADDRESS);
Jonathan Hart0f383542014-07-09 11:38:03 -0700542 ethPacket.setDestinationMACAddress(
543 LinkDiscoveryManager.LLDP_STANDARD_DST_MAC_STRING);
544 ethPacket.setPayload(lldpPacket);
545 ethPacket.setPad(true);
546
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700547 OFPacketIn pi = EasyMock.createMock(OFPacketIn.class);
548 expect(pi.getData()).andReturn(ethPacket.serialize()).anyTimes();
549 replay(pi);
Jonathan Hart0f383542014-07-09 11:38:03 -0700550
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700551 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Jonathan Hart0f383542014-07-09 11:38:03 -0700552
553 Link expectedLink = new Link(1L, 1, 2L, 2);
554
555 assertNull(linkDiscovery.links.get(expectedLink));
556
557 // Sending in the LLDP packet should cause the link to be created
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700558 Command command = linkDiscovery.handleLldp(lldpPacket, 2L, pi, (short) 2);
Jonathan Hart0f383542014-07-09 11:38:03 -0700559
560 assertEquals(Command.STOP, command);
561 assertNotNull(linkDiscovery.links.get(expectedLink));
562 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800563}