blob: 758c34e604c4225b32419d6d0e1944da9d65a18a [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.lldp.impl;
alshabib0ed6a202014-10-19 12:42:57 -070017
Thomas Vachuska27bee092015-06-23 19:03:10 -070018import com.google.common.collect.ArrayListMultimap;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070019import com.google.common.collect.ImmutableList;
Naoki Shiota399a0b32015-11-15 20:36:13 -060020import com.google.common.collect.ImmutableMap;
21import com.google.common.collect.ImmutableSet;
Thomas Vachuska27bee092015-06-23 19:03:10 -070022import com.google.common.collect.Lists;
23import com.google.common.collect.Maps;
alshabib0ed6a202014-10-19 12:42:57 -070024import org.junit.After;
25import org.junit.Before;
26import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080027import org.onlab.packet.ChassisId;
28import org.onlab.packet.Ethernet;
29import org.onlab.packet.ONOSLLDP;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070030import org.onosproject.cfg.ComponentConfigAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.cluster.NodeId;
32import org.onosproject.cluster.RoleInfo;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080033import org.onosproject.core.ApplicationId;
34import org.onosproject.core.CoreService;
35import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.mastership.MastershipListener;
37import org.onosproject.mastership.MastershipService;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070038import org.onosproject.net.Annotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080039import org.onosproject.net.ConnectPoint;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070040import org.onosproject.net.DefaultAnnotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080041import org.onosproject.net.DefaultDevice;
42import org.onosproject.net.DefaultPort;
43import org.onosproject.net.Device;
44import org.onosproject.net.DeviceId;
45import org.onosproject.net.MastershipRole;
46import org.onosproject.net.Port;
47import org.onosproject.net.PortNumber;
Naoki Shiota399a0b32015-11-15 20:36:13 -060048import org.onosproject.net.config.Config;
Naoki Shiota399a0b32015-11-15 20:36:13 -060049import org.onosproject.net.config.NetworkConfigEvent;
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -080050import org.onosproject.net.config.NetworkConfigEvent.Type;
Naoki Shiota399a0b32015-11-15 20:36:13 -060051import org.onosproject.net.config.NetworkConfigListener;
52import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080053import org.onosproject.net.device.DeviceEvent;
54import org.onosproject.net.device.DeviceListener;
55import org.onosproject.net.device.DeviceServiceAdapter;
56import org.onosproject.net.flow.TrafficTreatment;
57import org.onosproject.net.link.LinkDescription;
58import org.onosproject.net.link.LinkProvider;
59import org.onosproject.net.link.LinkProviderRegistry;
60import org.onosproject.net.link.LinkProviderService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -070061import org.onosproject.net.link.LinkServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080062import org.onosproject.net.packet.DefaultInboundPacket;
63import org.onosproject.net.packet.InboundPacket;
64import org.onosproject.net.packet.OutboundPacket;
65import org.onosproject.net.packet.PacketContext;
66import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070067import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080068import org.onosproject.net.provider.AbstractProviderService;
69import org.onosproject.net.provider.ProviderId;
alshabib0ed6a202014-10-19 12:42:57 -070070
Thomas Vachuska27bee092015-06-23 19:03:10 -070071import java.nio.ByteBuffer;
Thomas Vachuska27bee092015-06-23 19:03:10 -070072import java.util.HashMap;
Naoki Shiota399a0b32015-11-15 20:36:13 -060073import java.util.HashSet;
Thomas Vachuska27bee092015-06-23 19:03:10 -070074import java.util.List;
75import java.util.Map;
76import java.util.Set;
Naoki Shiota399a0b32015-11-15 20:36:13 -060077import java.util.Collections;
Thomas Vachuska27bee092015-06-23 19:03:10 -070078import java.util.concurrent.CompletableFuture;
79
Naoki Shiota399a0b32015-11-15 20:36:13 -060080import static org.easymock.EasyMock.createMock;
81import static org.easymock.EasyMock.expect;
82import static org.easymock.EasyMock.replay;
83
84import static org.junit.Assert.assertNull;
85import static org.junit.Assert.assertNotNull;
86import static org.junit.Assert.assertEquals;
87import static org.junit.Assert.assertTrue;
88import static org.onosproject.provider.lldp.impl.LldpLinkProvider.DEFAULT_RULES;
89import static org.junit.Assert.assertFalse;
90
alshabib0ed6a202014-10-19 12:42:57 -070091
Jonathan Hartb35540a2015-11-17 09:30:56 -080092public class LldpLinkProviderTest {
alshabib0ed6a202014-10-19 12:42:57 -070093
94 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
95 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070096 private static final DeviceId DID3 = DeviceId.deviceId("of:0000000000000003");
alshabib0ed6a202014-10-19 12:42:57 -070097
98 private static Port pd1;
99 private static Port pd2;
100 private static Port pd3;
101 private static Port pd4;
102
Jonathan Hartb35540a2015-11-17 09:30:56 -0800103 private final LldpLinkProvider provider = new LldpLinkProvider();
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700104 private final TestLinkRegistry linkRegistry = new TestLinkRegistry();
105 private final TestLinkService linkService = new TestLinkService();
alshabib0ed6a202014-10-19 12:42:57 -0700106 private final TestPacketService packetService = new TestPacketService();
107 private final TestDeviceService deviceService = new TestDeviceService();
108 private final TestMasterShipService masterService = new TestMasterShipService();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600109 private final TestNetworkConfigRegistry configRegistry = new TestNetworkConfigRegistry();
alshabib0ed6a202014-10-19 12:42:57 -0700110
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800111 private CoreService coreService;
alshabib0ed6a202014-10-19 12:42:57 -0700112 private TestLinkProviderService providerService;
113
114 private PacketProcessor testProcessor;
115 private DeviceListener deviceListener;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600116 private NetworkConfigListener configListener;
alshabib0ed6a202014-10-19 12:42:57 -0700117
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800118 private ApplicationId appId =
119 new DefaultApplicationId(100, "org.onosproject.provider.lldp");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800120
Naoki Shiota399a0b32015-11-15 20:36:13 -0600121 private TestSuppressionConfig cfg;
122
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800123 private Set<DeviceId> deviceBlacklist;
124
125 private Set<ConnectPoint> portBlacklist;
126
alshabib0ed6a202014-10-19 12:42:57 -0700127 @Before
128 public void setUp() {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800129 deviceBlacklist = new HashSet<>();
130 portBlacklist = new HashSet<>();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600131 cfg = new TestSuppressionConfig();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800132 coreService = createMock(CoreService.class);
133 expect(coreService.registerApplication(appId.name()))
134 .andReturn(appId).anyTimes();
135 replay(coreService);
136
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700137 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800138 provider.coreService = coreService;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600139 provider.cfgRegistry = configRegistry;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800140
alshabib0ed6a202014-10-19 12:42:57 -0700141 provider.deviceService = deviceService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700142 provider.linkService = linkService;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800143 provider.packetService = packetService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700144 provider.providerRegistry = linkRegistry;
alshabib0ed6a202014-10-19 12:42:57 -0700145 provider.masterService = masterService;
146
Saurav Dasc313c402015-02-27 10:09:47 -0800147 provider.activate(null);
alshabib0ed6a202014-10-19 12:42:57 -0700148 }
149
150 @Test
151 public void basics() {
152 assertNotNull("registration expected", providerService);
153 assertEquals("incorrect provider", provider, providerService.provider());
154 }
155
156 @Test
157 public void switchAdd() {
158 DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
159 deviceListener.event(de);
160
161 assertFalse("Device not added", provider.discoverers.isEmpty());
162 }
163
164 @Test
165 public void switchRemove() {
166 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
167 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
168
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700169 final LinkDiscovery linkDiscovery = provider.discoverers.get(DID1);
170 if (linkDiscovery != null) {
171 // If LinkDiscovery helper is there after DEVICE_REMOVED,
172 // it should be stopped
173 assertTrue("Discoverer is not stopped", linkDiscovery.isStopped());
174 }
alshabib0ed6a202014-10-19 12:42:57 -0700175 assertTrue("Device is not gone.", vanishedDpid(DID1));
176 }
177
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700178 /**
179 * Checks that links on a reconfigured switch are properly removed.
180 */
181 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800182 public void switchSuppressedByAnnotation() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600183
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700184 // add device to stub DeviceService
185 deviceService.putDevice(device(DID3));
186 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
187
188 assertFalse("Device not added", provider.discoverers.isEmpty());
189
190 // update device in stub DeviceService with suppression config
191 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800192 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700193 .build()));
194 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
195
Naoki Shiota399a0b32015-11-15 20:36:13 -0600196 // discovery on device is expected to be gone or stopped
197 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
198 if (linkDiscovery != null) {
199 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
200 }
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700201 }
202
alshabib0ed6a202014-10-19 12:42:57 -0700203 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800204 public void switchSuppressByBlacklist() {
205 // add device in stub DeviceService
206 deviceService.putDevice(device(DID3));
207 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
208
209 // add deviveId to device blacklist
210 deviceBlacklist.add(DID3);
211 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
212 DID3,
213 LinkDiscoveryFromDevice.class));
214
215 // discovery helper for device is expected to be gone or stopped
216 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
217 if (linkDiscovery != null) {
218 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
219 }
220
221 }
222
223 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700224 public void portUp() {
225 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
226 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
227
228 assertTrue("Port not added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700229 provider.discoverers.get(DID1).containsPort(3L));
alshabib0ed6a202014-10-19 12:42:57 -0700230 }
231
232 @Test
233 public void portDown() {
234
235 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
236 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
237
alshabib0ed6a202014-10-19 12:42:57 -0700238 assertFalse("Port added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700239 provider.discoverers.get(DID1).containsPort(1L));
240 assertTrue("Port is not gone.", vanishedPort(1L));
alshabib0ed6a202014-10-19 12:42:57 -0700241 }
242
243 @Test
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700244 public void portRemoved() {
245 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
246 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
247 deviceListener.event(portEvent(DeviceEvent.Type.PORT_REMOVED, DID1, port(DID1, 3, true)));
248
249 assertTrue("Port is not gone.", vanishedPort(3L));
250 assertFalse("Port was not removed from discoverer",
251 provider.discoverers.get(DID1).containsPort(3L));
252 }
253
254 /**
255 * Checks that discovery on reconfigured switch are properly restarted.
256 */
257 @Test
Naoki Shiota399a0b32015-11-15 20:36:13 -0600258 public void portSuppressedByDeviceAnnotationConfig() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700259
260 /// When Device is configured with suppression:ON, Port also is same
261
262 // add device in stub DeviceService with suppression configured
263 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800264 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700265 .build()));
266 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
267
268 // non-suppressed port added to suppressed device
269 final long portno3 = 3L;
270 deviceService.putPorts(DID3, port(DID3, portno3, true));
271 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
272
273 // discovery on device is expected to be stopped
274 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
275 if (linkDiscovery != null) {
276 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
277 }
278
279 /// When Device is reconfigured without suppression:OFF,
280 /// Port should be included for discovery
281
282 // update device in stub DeviceService without suppression configured
283 deviceService.putDevice(device(DID3));
284 // update the Port in stub DeviceService. (Port has reference to Device)
285 deviceService.putPorts(DID3, port(DID3, portno3, true));
286 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
287
288 // discovery should come back on
289 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
290 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
291 }
292
293 /**
Naoki Shiota399a0b32015-11-15 20:36:13 -0600294 * Checks that discovery on reconfigured switch are properly restarted.
295 */
296 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800297 public void portSuppressedByParentDeviceIdBlacklist() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600298
299 /// When Device is configured without suppression:OFF,
300 /// Port should be included for discovery
301
302 // add device in stub DeviceService without suppression configured
303 deviceService.putDevice(device(DID3));
304 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
305
306 // non-suppressed port added to suppressed device
307 final long portno3 = 3L;
308 deviceService.putPorts(DID3, port(DID3, portno3, true));
309 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
310
311 // discovery should succeed
312 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
313 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
314
315 // add suppression rule for "deviceId: "of:0000000000000003""
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800316 deviceBlacklist.add(DID3);
317 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
318 DID3,
319 LinkDiscoveryFromDevice.class));
320
Naoki Shiota399a0b32015-11-15 20:36:13 -0600321
322 /// When Device is reconfigured with suppression:ON, Port also is same
323
324 // update device in stub DeviceService with suppression configured
325 deviceService.putDevice(device(DID3));
326 // update the Port in stub DeviceService. (Port has reference to Device)
327 deviceService.putPorts(DID3, port(DID3, portno3, true));
328 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
329
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800330 // discovery helper for device is expected to be gone or stopped
Naoki Shiota399a0b32015-11-15 20:36:13 -0600331 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
332 if (linkDiscovery != null) {
333 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
334 }
335 }
336
337 /**
338 * Checks that discovery on reconfigured switch are properly restarted.
339 */
340 @Test
341 public void portSuppressedByDeviceTypeConfig() {
342
343 /// When Device is configured without suppression:OFF,
344 /// Port should be included for discovery
345
346 // add device in stub DeviceService without suppression configured
347 deviceService.putDevice(device(DID1, Device.Type.SWITCH));
348 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
349
350 // non-suppressed port added to suppressed device
351 final long portno3 = 3L;
352 deviceService.putPorts(DID1, port(DID1, portno3, true));
353 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, portno3, true)));
354
355 // add device in stub DeviceService with suppression configured
356 deviceService.putDevice(device(DID2, Device.Type.ROADM));
357 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
358
359 // non-suppressed port added to suppressed device
360 final long portno4 = 4L;
361 deviceService.putPorts(DID2, port(DID2, portno4, true));
362 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, portno4, true)));
363
364 // discovery should succeed for this device
365 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID1).isStopped());
366 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID1).containsPort(portno3));
367
368 // discovery on device is expected to be stopped for this device
369 LinkDiscovery linkDiscovery = provider.discoverers.get(DID2);
370 if (linkDiscovery != null) {
371 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
372 }
373 }
374
375 /**
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700376 * Checks that discovery on reconfigured port are properly restarted.
377 */
378 @Test
379 public void portSuppressedByPortConfig() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600380
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700381 // add device in stub DeviceService without suppression configured
382 deviceService.putDevice(device(DID3));
383 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
384
385 // suppressed port added to non-suppressed device
386 final long portno3 = 3L;
387 final Port port3 = port(DID3, portno3, true,
388 DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800389 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700390 .build());
391 deviceService.putPorts(DID3, port3);
392 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
393
394 // discovery helper should be there turned on
395 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
396 assertFalse("Discoverer should not contain the port there",
397 provider.discoverers.get(DID3).containsPort(portno3));
398 }
399
400 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800401 public void portSuppressedByPortBlacklist() {
402
403 // add device in stub DeviceService without suppression configured
404 deviceService.putDevice(device(DID3));
405 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
406
407 final long portno3 = 3L;
408 final Port port3 = port(DID3, portno3, true);
409
410 final ConnectPoint cpDid3no3 = new ConnectPoint(DID3, PortNumber.portNumber(portno3));
411 portBlacklist.add(cpDid3no3);
412
413 // suppressed port added to non-suppressed device
414 deviceService.putPorts(DID3, port3);
415 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
416
417 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
418 cpDid3no3,
419 LinkDiscoveryFromPort.class));
420
421 // discovery helper should be there turned on
422 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
423 // but port is not a discovery target
424 assertFalse("Discoverer should not contain the port there",
425 provider.discoverers.get(DID3).containsPort(portno3));
426 }
427
428 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700429 public void portUnknown() {
430 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700431 // Note: DID3 hasn't been added to TestDeviceService, but only port is added
432 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, 1, false)));
alshabib0ed6a202014-10-19 12:42:57 -0700433
434
alshabibdfc7afb2014-10-21 20:13:27 -0700435 assertNull("DeviceId exists",
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700436 provider.discoverers.get(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700437 }
438
439 @Test
440 public void unknownPktCtx() {
441
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700442 // Note: DID3 hasn't been added to TestDeviceService
443 PacketContext pktCtx = new TestPacketContext(device(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700444
445 testProcessor.process(pktCtx);
446 assertFalse("Context should still be free", pktCtx.isHandled());
447 }
448
449 @Test
450 public void knownPktCtx() {
451 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
452 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
453 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
454
455
456 testProcessor.process(pktCtx);
457
458 assertTrue("Link not detected", detectedLink(DID1, DID2));
459
460 }
461
462
463 @After
464 public void tearDown() {
465 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800466 provider.coreService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700467 provider.providerRegistry = null;
468 provider.deviceService = null;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800469 provider.packetService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700470 }
471
472 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
473 return new DeviceEvent(type, deviceService.getDevice(did));
474
475 }
476
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700477 private DefaultDevice device(DeviceId did) {
478 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
479 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
480 }
481
Naoki Shiota399a0b32015-11-15 20:36:13 -0600482 private DefaultDevice device(DeviceId did, Device.Type type) {
483 return new DefaultDevice(ProviderId.NONE, did, type,
484 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
485 }
486
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700487 private DefaultDevice device(DeviceId did, Annotations annotations) {
488 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
489 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId(), annotations);
490 }
491
Saurav Dasc313c402015-02-27 10:09:47 -0800492 @SuppressWarnings(value = { "unused" })
alshabib0ed6a202014-10-19 12:42:57 -0700493 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
494 return new DeviceEvent(type, deviceService.getDevice(did),
495 deviceService.getPort(did, port));
496 }
497
498 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
499 return new DeviceEvent(type, deviceService.getDevice(did), port);
500 }
501
502 private Port port(DeviceId did, long port, boolean enabled) {
503 return new DefaultPort(deviceService.getDevice(did),
504 PortNumber.portNumber(port), enabled);
505 }
506
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700507 private Port port(DeviceId did, long port, boolean enabled, Annotations annotations) {
508 return new DefaultPort(deviceService.getDevice(did),
509 PortNumber.portNumber(port), enabled, annotations);
510 }
alshabib0ed6a202014-10-19 12:42:57 -0700511
512 private boolean vanishedDpid(DeviceId... dids) {
513 for (int i = 0; i < dids.length; i++) {
514 if (!providerService.vanishedDpid.contains(dids[i])) {
515 return false;
516 }
517 }
518 return true;
519 }
520
521 private boolean vanishedPort(Long... ports) {
522 for (int i = 0; i < ports.length; i++) {
523 if (!providerService.vanishedPort.contains(ports[i])) {
524 return false;
525 }
526 }
527 return true;
528 }
529
530 private boolean detectedLink(DeviceId src, DeviceId dst) {
531 for (DeviceId key : providerService.discoveredLinks.keySet()) {
532 if (key.equals(src)) {
533 return providerService.discoveredLinks.get(src).equals(dst);
534 }
535 }
536 return false;
537 }
538
Naoki Shiota399a0b32015-11-15 20:36:13 -0600539 @Test
540 public void addDeviceTypeRule() {
541 Device.Type deviceType1 = Device.Type.ROADM;
542 Device.Type deviceType2 = Device.Type.SWITCH;
543
544 Set<Device.Type> deviceTypes = new HashSet<>();
545 deviceTypes.add(deviceType1);
546
547 cfg.deviceTypes(deviceTypes);
548
549 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
550
551 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
552 assertFalse(provider.rules().getSuppressedDeviceType().contains(deviceType2));
553 }
554
555 @Test
556 public void updateDeviceTypeRule() {
557 Device.Type deviceType1 = Device.Type.ROADM;
558 Device.Type deviceType2 = Device.Type.SWITCH;
559 Set<Device.Type> deviceTypes = new HashSet<>();
560
561 deviceTypes.add(deviceType1);
562 cfg.deviceTypes(deviceTypes);
563
564 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
565
566 deviceTypes.add(deviceType2);
567 cfg.deviceTypes(deviceTypes);
568
569 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
570
571 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
572 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType2));
573 }
574
575 @Test
576 public void addAnnotationRule() {
577 final String key1 = "key1", key2 = "key2";
578 final String value1 = "value1";
579
580 Map<String, String> annotation = new HashMap<>();
581 annotation.put(key1, value1);
582
583 cfg.annotation(annotation);
584
585 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
586
587 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
588 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
589 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
590 }
591
592 @Test
593 public void updateAnnotationRule() {
594 final String key1 = "key1", key2 = "key2";
595 final String value1 = "value1", value2 = "value2";
596 Map<String, String> annotation = new HashMap<>();
597
598 annotation.put(key1, value1);
599 cfg.annotation(annotation);
600
601 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
602
603 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
604 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
605 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
606
607 annotation.put(key2, value2);
608 cfg.annotation(annotation);
609
610 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
611
612 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
613 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
614 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key2));
615 assertEquals(value2, provider.rules().getSuppressedAnnotation().get(key2));
616 }
617
618 private void configEvent(NetworkConfigEvent.Type evType) {
619 configListener.event(new NetworkConfigEvent(evType,
620 appId,
621 SuppressionConfig.class));
622 }
623
624
alshabib0ed6a202014-10-19 12:42:57 -0700625 private class TestLinkRegistry implements LinkProviderRegistry {
626
627 @Override
628 public LinkProviderService register(LinkProvider provider) {
629 providerService = new TestLinkProviderService(provider);
630 return providerService;
631 }
632
633 @Override
634 public void unregister(LinkProvider provider) {
635 }
636
637 @Override
638 public Set<ProviderId> getProviders() {
639 return null;
640 }
641
642 }
643
644 private class TestLinkProviderService
645 extends AbstractProviderService<LinkProvider>
646 implements LinkProviderService {
647
648 List<DeviceId> vanishedDpid = Lists.newLinkedList();
649 List<Long> vanishedPort = Lists.newLinkedList();
650 Map<DeviceId, DeviceId> discoveredLinks = Maps.newHashMap();
651
652 protected TestLinkProviderService(LinkProvider provider) {
653 super(provider);
654 }
655
656 @Override
657 public void linkDetected(LinkDescription linkDescription) {
658 DeviceId sDid = linkDescription.src().deviceId();
659 DeviceId dDid = linkDescription.dst().deviceId();
660 discoveredLinks.put(sDid, dDid);
661 }
662
663 @Override
664 public void linkVanished(LinkDescription linkDescription) {
alshabib0ed6a202014-10-19 12:42:57 -0700665 }
666
667 @Override
668 public void linksVanished(ConnectPoint connectPoint) {
669 vanishedPort.add(connectPoint.port().toLong());
670
671 }
672
673 @Override
674 public void linksVanished(DeviceId deviceId) {
675 vanishedDpid.add(deviceId);
676 }
677
678
679 }
680
681
682
683 private class TestPacketContext implements PacketContext {
684
685 protected Device device;
686 protected boolean blocked = false;
687
688 public TestPacketContext(Device dev) {
689 device = dev;
690 }
691
692 @Override
693 public long time() {
694 return 0;
695 }
696
697 @Override
698 public InboundPacket inPacket() {
699 ONOSLLDP lldp = new ONOSLLDP();
700 lldp.setChassisId(device.chassisId());
701 lldp.setPortId((int) pd1.number().toLong());
702 lldp.setDevice(deviceService.getDevice(DID1).id().toString());
703
704
705 Ethernet ethPacket = new Ethernet();
706 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
707 ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
708 ethPacket.setPayload(lldp);
709 ethPacket.setPad(true);
710
711
712
713 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
714
715 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
716
717 return new DefaultInboundPacket(cp, ethPacket,
718 ByteBuffer.wrap(ethPacket.serialize()));
719
720 }
721
722 @Override
723 public OutboundPacket outPacket() {
724 return null;
725 }
726
727 @Override
728 public TrafficTreatment.Builder treatmentBuilder() {
729 return null;
730 }
731
732 @Override
733 public void send() {
734
735 }
736
737 @Override
738 public boolean block() {
739 blocked = true;
740 return blocked;
741 }
742
743 @Override
744 public boolean isHandled() {
745 return blocked;
746 }
747
748 }
749
Thomas Vachuska27bee092015-06-23 19:03:10 -0700750 private class TestPacketService extends PacketServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700751 @Override
752 public void addProcessor(PacketProcessor processor, int priority) {
753 testProcessor = processor;
754 }
alshabib0ed6a202014-10-19 12:42:57 -0700755 }
756
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800757 private class TestDeviceService extends DeviceServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700758
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700759 private final Map<DeviceId, Device> devices = new HashMap<>();
alshabib0ed6a202014-10-19 12:42:57 -0700760 private final ArrayListMultimap<DeviceId, Port> ports =
761 ArrayListMultimap.create();
alshabib0ed6a202014-10-19 12:42:57 -0700762 public TestDeviceService() {
763 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
764 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
765 Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH,
766 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
767 devices.put(DID1, d1);
768 devices.put(DID2, d2);
alshabib0ed6a202014-10-19 12:42:57 -0700769 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
770 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
771 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
772 pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true);
773
774 ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
775 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
alshabib0ed6a202014-10-19 12:42:57 -0700776 }
777
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700778 private void putDevice(Device device) {
779 DeviceId deviceId = device.id();
780 devices.put(deviceId, device);
781 }
782
783 private void putPorts(DeviceId did, Port...ports) {
784 this.ports.putAll(did, Lists.newArrayList(ports));
785 }
786
alshabib0ed6a202014-10-19 12:42:57 -0700787 @Override
788 public int getDeviceCount() {
789 return devices.values().size();
790 }
791
792 @Override
793 public Iterable<Device> getDevices() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700794 return ImmutableList.copyOf(devices.values());
alshabib0ed6a202014-10-19 12:42:57 -0700795 }
796
797 @Override
798 public Device getDevice(DeviceId deviceId) {
799 return devices.get(deviceId);
800 }
801
802 @Override
803 public MastershipRole getRole(DeviceId deviceId) {
804 return MastershipRole.MASTER;
805 }
806
807 @Override
808 public List<Port> getPorts(DeviceId deviceId) {
809 return ports.get(deviceId);
810 }
811
812 @Override
813 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
814 for (Port p : ports.get(deviceId)) {
815 if (p.number().equals(portNumber)) {
816 return p;
817 }
818 }
819 return null;
820 }
821
822 @Override
823 public boolean isAvailable(DeviceId deviceId) {
824 return true;
825 }
826
827 @Override
828 public void addListener(DeviceListener listener) {
829 deviceListener = listener;
830
831 }
832
833 @Override
834 public void removeListener(DeviceListener listener) {
835
836 }
837 }
838
839 private final class TestMasterShipService implements MastershipService {
840
841 @Override
842 public MastershipRole getLocalRole(DeviceId deviceId) {
843 return MastershipRole.MASTER;
844 }
845
846 @Override
Madan Jampanide003d92015-05-11 17:14:20 -0700847 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
848 return CompletableFuture.completedFuture(null);
alshabib0ed6a202014-10-19 12:42:57 -0700849 }
850
851 @Override
Madan Jampanic6e574f2015-05-29 13:41:52 -0700852 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
853 return null;
alshabib0ed6a202014-10-19 12:42:57 -0700854 }
855
856 @Override
857 public NodeId getMasterFor(DeviceId deviceId) {
858 return null;
859 }
860
861 @Override
862 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
863 return null;
864 }
865
866 @Override
alshabib0ed6a202014-10-19 12:42:57 -0700867 public void addListener(MastershipListener listener) {
868
869 }
870
871 @Override
872 public void removeListener(MastershipListener listener) {
873
874 }
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700875
876 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700877 public RoleInfo getNodesFor(DeviceId deviceId) {
878 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700879 }
alshabib0ed6a202014-10-19 12:42:57 -0700880 }
881
882
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700883 private class TestLinkService extends LinkServiceAdapter {
884 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600885
886 private final class TestNetworkConfigRegistry
887 extends NetworkConfigRegistryAdapter {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800888 @SuppressWarnings("unchecked")
Naoki Shiota399a0b32015-11-15 20:36:13 -0600889 @Override
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800890 public <S, C extends Config<S>> C getConfig(S subj, Class<C> configClass) {
891 if (configClass == SuppressionConfig.class) {
892 return (C) cfg;
893 } else if (configClass == LinkDiscoveryFromDevice.class) {
894 return (C) new LinkDiscoveryFromDevice() {
895 @Override
896 public boolean enabled() {
897 return !deviceBlacklist.contains(subj);
898 }
899 };
900 } else if (configClass == LinkDiscoveryFromPort.class) {
901 return (C) new LinkDiscoveryFromPort() {
902 @Override
903 public boolean enabled() {
904 return !portBlacklist.contains(subj);
905 }
906 };
907 } else {
908 return null;
909 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600910 }
911
912 @Override
913 public void addListener(NetworkConfigListener listener) {
914 configListener = listener;
915 }
916 }
917
918 private final class TestSuppressionConfig extends SuppressionConfig {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600919 private Set<Device.Type> deviceTypes = new HashSet<>(DEFAULT_RULES.getSuppressedDeviceType());
920 private Map<String, String> annotation = new HashMap<>(DEFAULT_RULES.getSuppressedAnnotation());
921
922 @Override
Naoki Shiota399a0b32015-11-15 20:36:13 -0600923 public Set<Device.Type> deviceTypes() {
924 return ImmutableSet.copyOf(deviceTypes);
925 }
926
927 @Override
928 public SuppressionConfig deviceTypes(Set<Device.Type> deviceTypes) {
929 this.deviceTypes = ImmutableSet.copyOf(deviceTypes);
930 return this;
931 }
932
933 @Override
934 public Map<String, String> annotation() {
935 return ImmutableMap.copyOf(annotation);
936 }
937
938 @Override
939 public SuppressionConfig annotation(Map<String, String> annotation) {
940 this.annotation = ImmutableMap.copyOf(annotation);
941 return this;
942 }
943 }
alshabib0ed6a202014-10-19 12:42:57 -0700944}