blob: 20d615aa658a964f3442111d19d6b83daa04c130 [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
Ray Milkeycd6ab182016-02-03 11:13:09 -080018import java.nio.ByteBuffer;
19import java.util.Collections;
20import java.util.HashMap;
21import java.util.HashSet;
22import java.util.List;
23import java.util.Map;
24import java.util.Set;
25import java.util.concurrent.CompletableFuture;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080026
alshabib0ed6a202014-10-19 12:42:57 -070027import org.junit.After;
28import org.junit.Before;
29import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080030import org.onlab.packet.ChassisId;
31import org.onlab.packet.Ethernet;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080032import org.onlab.packet.IpAddress;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080033import org.onlab.packet.ONOSLLDP;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070034import org.onosproject.cfg.ComponentConfigAdapter;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080035import org.onosproject.cluster.ClusterMetadata;
Madan Jampaniab7e7cd2016-01-14 14:02:32 -080036import org.onosproject.cluster.ClusterMetadataEventListener;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080037import org.onosproject.cluster.ClusterMetadataService;
38import org.onosproject.cluster.ControllerNode;
39import org.onosproject.cluster.DefaultControllerNode;
Madan Jampani8474fdd2016-01-19 09:56:28 -080040import org.onosproject.cluster.DefaultPartition;
Brian O'Connorabafb502014-12-02 22:26:20 -080041import org.onosproject.cluster.NodeId;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080042import org.onosproject.cluster.Partition;
Madan Jampaniab7e7cd2016-01-14 14:02:32 -080043import org.onosproject.cluster.PartitionId;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.cluster.RoleInfo;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080045import org.onosproject.core.ApplicationId;
46import org.onosproject.core.CoreService;
47import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080048import org.onosproject.mastership.MastershipListener;
49import org.onosproject.mastership.MastershipService;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070050import org.onosproject.net.Annotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080051import org.onosproject.net.ConnectPoint;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070052import org.onosproject.net.DefaultAnnotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080053import org.onosproject.net.DefaultDevice;
54import org.onosproject.net.DefaultPort;
55import org.onosproject.net.Device;
56import org.onosproject.net.DeviceId;
57import org.onosproject.net.MastershipRole;
58import org.onosproject.net.Port;
59import org.onosproject.net.PortNumber;
Naoki Shiota399a0b32015-11-15 20:36:13 -060060import org.onosproject.net.config.Config;
Naoki Shiota399a0b32015-11-15 20:36:13 -060061import org.onosproject.net.config.NetworkConfigEvent;
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -080062import org.onosproject.net.config.NetworkConfigEvent.Type;
Naoki Shiota399a0b32015-11-15 20:36:13 -060063import org.onosproject.net.config.NetworkConfigListener;
64import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080065import org.onosproject.net.device.DeviceEvent;
66import org.onosproject.net.device.DeviceListener;
67import org.onosproject.net.device.DeviceServiceAdapter;
68import org.onosproject.net.flow.TrafficTreatment;
Ray Milkeycd6ab182016-02-03 11:13:09 -080069import org.onosproject.net.link.LinkProviderRegistryAdapter;
70import org.onosproject.net.link.LinkProviderServiceAdapter;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -070071import org.onosproject.net.link.LinkServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080072import org.onosproject.net.packet.DefaultInboundPacket;
73import org.onosproject.net.packet.InboundPacket;
74import org.onosproject.net.packet.OutboundPacket;
75import org.onosproject.net.packet.PacketContext;
76import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070077import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080078import org.onosproject.net.provider.ProviderId;
alshabib0ed6a202014-10-19 12:42:57 -070079
Ray Milkeycd6ab182016-02-03 11:13:09 -080080import com.google.common.collect.ArrayListMultimap;
81import com.google.common.collect.ImmutableList;
82import com.google.common.collect.ImmutableMap;
83import com.google.common.collect.ImmutableSet;
84import com.google.common.collect.Lists;
85import com.google.common.collect.Sets;
Thomas Vachuska27bee092015-06-23 19:03:10 -070086
Naoki Shiota399a0b32015-11-15 20:36:13 -060087import static org.easymock.EasyMock.createMock;
88import static org.easymock.EasyMock.expect;
89import static org.easymock.EasyMock.replay;
Naoki Shiota399a0b32015-11-15 20:36:13 -060090import static org.junit.Assert.assertEquals;
Ray Milkeycd6ab182016-02-03 11:13:09 -080091import static org.junit.Assert.assertFalse;
92import static org.junit.Assert.assertNotNull;
93import static org.junit.Assert.assertNull;
Naoki Shiota399a0b32015-11-15 20:36:13 -060094import static org.junit.Assert.assertTrue;
95import static org.onosproject.provider.lldp.impl.LldpLinkProvider.DEFAULT_RULES;
Naoki Shiota399a0b32015-11-15 20:36:13 -060096
alshabib0ed6a202014-10-19 12:42:57 -070097
Jonathan Hartb35540a2015-11-17 09:30:56 -080098public class LldpLinkProviderTest {
alshabib0ed6a202014-10-19 12:42:57 -070099
100 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
101 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700102 private static final DeviceId DID3 = DeviceId.deviceId("of:0000000000000003");
alshabib0ed6a202014-10-19 12:42:57 -0700103
104 private static Port pd1;
105 private static Port pd2;
106 private static Port pd3;
107 private static Port pd4;
108
Jonathan Hartb35540a2015-11-17 09:30:56 -0800109 private final LldpLinkProvider provider = new LldpLinkProvider();
Ray Milkeycd6ab182016-02-03 11:13:09 -0800110 private final LinkProviderRegistryAdapter linkRegistry = new LinkProviderRegistryAdapter();
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700111 private final TestLinkService linkService = new TestLinkService();
alshabib0ed6a202014-10-19 12:42:57 -0700112 private final TestPacketService packetService = new TestPacketService();
113 private final TestDeviceService deviceService = new TestDeviceService();
114 private final TestMasterShipService masterService = new TestMasterShipService();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600115 private final TestNetworkConfigRegistry configRegistry = new TestNetworkConfigRegistry();
alshabib0ed6a202014-10-19 12:42:57 -0700116
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800117 private CoreService coreService;
Ray Milkeycd6ab182016-02-03 11:13:09 -0800118 private LinkProviderServiceAdapter providerService;
alshabib0ed6a202014-10-19 12:42:57 -0700119
120 private PacketProcessor testProcessor;
121 private DeviceListener deviceListener;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600122 private NetworkConfigListener configListener;
alshabib0ed6a202014-10-19 12:42:57 -0700123
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800124 private ApplicationId appId =
125 new DefaultApplicationId(100, "org.onosproject.provider.lldp");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800126
Naoki Shiota399a0b32015-11-15 20:36:13 -0600127 private TestSuppressionConfig cfg;
128
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800129 private Set<DeviceId> deviceBlacklist;
130
131 private Set<ConnectPoint> portBlacklist;
132
alshabib0ed6a202014-10-19 12:42:57 -0700133 @Before
134 public void setUp() {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800135 deviceBlacklist = new HashSet<>();
136 portBlacklist = new HashSet<>();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600137 cfg = new TestSuppressionConfig();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800138 coreService = createMock(CoreService.class);
139 expect(coreService.registerApplication(appId.name()))
140 .andReturn(appId).anyTimes();
141 replay(coreService);
142
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700143 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800144 provider.coreService = coreService;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600145 provider.cfgRegistry = configRegistry;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800146
alshabib0ed6a202014-10-19 12:42:57 -0700147 provider.deviceService = deviceService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700148 provider.linkService = linkService;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800149 provider.packetService = packetService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700150 provider.providerRegistry = linkRegistry;
alshabib0ed6a202014-10-19 12:42:57 -0700151 provider.masterService = masterService;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800152 provider.clusterMetadataService = new TestMetadataService();
Ray Milkeycd6ab182016-02-03 11:13:09 -0800153
Saurav Dasc313c402015-02-27 10:09:47 -0800154 provider.activate(null);
Ray Milkeycd6ab182016-02-03 11:13:09 -0800155
156 providerService = linkRegistry.registeredProvider();
alshabib0ed6a202014-10-19 12:42:57 -0700157 }
158
159 @Test
160 public void basics() {
161 assertNotNull("registration expected", providerService);
162 assertEquals("incorrect provider", provider, providerService.provider());
163 }
164
165 @Test
166 public void switchAdd() {
167 DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
168 deviceListener.event(de);
169
170 assertFalse("Device not added", provider.discoverers.isEmpty());
171 }
172
173 @Test
174 public void switchRemove() {
175 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
176 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
177
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700178 final LinkDiscovery linkDiscovery = provider.discoverers.get(DID1);
179 if (linkDiscovery != null) {
180 // If LinkDiscovery helper is there after DEVICE_REMOVED,
181 // it should be stopped
182 assertTrue("Discoverer is not stopped", linkDiscovery.isStopped());
183 }
alshabib0ed6a202014-10-19 12:42:57 -0700184 assertTrue("Device is not gone.", vanishedDpid(DID1));
185 }
186
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700187 /**
188 * Checks that links on a reconfigured switch are properly removed.
189 */
190 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800191 public void switchSuppressedByAnnotation() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600192
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700193 // add device to stub DeviceService
194 deviceService.putDevice(device(DID3));
195 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
196
197 assertFalse("Device not added", provider.discoverers.isEmpty());
198
199 // update device in stub DeviceService with suppression config
200 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800201 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700202 .build()));
203 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
204
Naoki Shiota399a0b32015-11-15 20:36:13 -0600205 // discovery on device is expected to be gone or stopped
206 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
207 if (linkDiscovery != null) {
208 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
209 }
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700210 }
211
alshabib0ed6a202014-10-19 12:42:57 -0700212 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800213 public void switchSuppressByBlacklist() {
214 // add device in stub DeviceService
215 deviceService.putDevice(device(DID3));
216 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
217
218 // add deviveId to device blacklist
219 deviceBlacklist.add(DID3);
220 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
221 DID3,
222 LinkDiscoveryFromDevice.class));
223
224 // discovery helper for device is expected to be gone or stopped
225 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
226 if (linkDiscovery != null) {
227 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
228 }
229
230 }
231
232 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700233 public void portUp() {
234 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
235 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
236
237 assertTrue("Port not added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700238 provider.discoverers.get(DID1).containsPort(3L));
alshabib0ed6a202014-10-19 12:42:57 -0700239 }
240
241 @Test
242 public void portDown() {
243
244 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
245 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
246
alshabib0ed6a202014-10-19 12:42:57 -0700247 assertFalse("Port added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700248 provider.discoverers.get(DID1).containsPort(1L));
249 assertTrue("Port is not gone.", vanishedPort(1L));
alshabib0ed6a202014-10-19 12:42:57 -0700250 }
251
252 @Test
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700253 public void portRemoved() {
254 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
255 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
256 deviceListener.event(portEvent(DeviceEvent.Type.PORT_REMOVED, DID1, port(DID1, 3, true)));
257
258 assertTrue("Port is not gone.", vanishedPort(3L));
259 assertFalse("Port was not removed from discoverer",
260 provider.discoverers.get(DID1).containsPort(3L));
261 }
262
263 /**
264 * Checks that discovery on reconfigured switch are properly restarted.
265 */
266 @Test
Naoki Shiota399a0b32015-11-15 20:36:13 -0600267 public void portSuppressedByDeviceAnnotationConfig() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700268
269 /// When Device is configured with suppression:ON, Port also is same
270
271 // add device in stub DeviceService with suppression configured
272 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800273 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700274 .build()));
275 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
276
277 // non-suppressed port added to suppressed device
278 final long portno3 = 3L;
279 deviceService.putPorts(DID3, port(DID3, portno3, true));
280 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
281
282 // discovery on device is expected to be stopped
283 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
284 if (linkDiscovery != null) {
285 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
286 }
287
288 /// When Device is reconfigured without suppression:OFF,
289 /// Port should be included for discovery
290
291 // update device in stub DeviceService without suppression configured
292 deviceService.putDevice(device(DID3));
293 // update the Port in stub DeviceService. (Port has reference to Device)
294 deviceService.putPorts(DID3, port(DID3, portno3, true));
295 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
296
297 // discovery should come back on
298 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
299 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
300 }
301
302 /**
Naoki Shiota399a0b32015-11-15 20:36:13 -0600303 * Checks that discovery on reconfigured switch are properly restarted.
304 */
305 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800306 public void portSuppressedByParentDeviceIdBlacklist() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600307
308 /// When Device is configured without suppression:OFF,
309 /// Port should be included for discovery
310
311 // add device in stub DeviceService without suppression configured
312 deviceService.putDevice(device(DID3));
313 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
314
315 // non-suppressed port added to suppressed device
316 final long portno3 = 3L;
317 deviceService.putPorts(DID3, port(DID3, portno3, true));
318 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
319
320 // discovery should succeed
321 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
322 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
323
324 // add suppression rule for "deviceId: "of:0000000000000003""
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800325 deviceBlacklist.add(DID3);
326 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
327 DID3,
328 LinkDiscoveryFromDevice.class));
329
Naoki Shiota399a0b32015-11-15 20:36:13 -0600330
331 /// When Device is reconfigured with suppression:ON, Port also is same
332
333 // update device in stub DeviceService with suppression configured
334 deviceService.putDevice(device(DID3));
335 // update the Port in stub DeviceService. (Port has reference to Device)
336 deviceService.putPorts(DID3, port(DID3, portno3, true));
337 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
338
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800339 // discovery helper for device is expected to be gone or stopped
Naoki Shiota399a0b32015-11-15 20:36:13 -0600340 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
341 if (linkDiscovery != null) {
342 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
343 }
344 }
345
346 /**
347 * Checks that discovery on reconfigured switch are properly restarted.
348 */
349 @Test
350 public void portSuppressedByDeviceTypeConfig() {
351
352 /// When Device is configured without suppression:OFF,
353 /// Port should be included for discovery
354
355 // add device in stub DeviceService without suppression configured
356 deviceService.putDevice(device(DID1, Device.Type.SWITCH));
357 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
358
359 // non-suppressed port added to suppressed device
360 final long portno3 = 3L;
361 deviceService.putPorts(DID1, port(DID1, portno3, true));
362 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, portno3, true)));
363
364 // add device in stub DeviceService with suppression configured
365 deviceService.putDevice(device(DID2, Device.Type.ROADM));
366 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
367
368 // non-suppressed port added to suppressed device
369 final long portno4 = 4L;
370 deviceService.putPorts(DID2, port(DID2, portno4, true));
371 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, portno4, true)));
372
373 // discovery should succeed for this device
374 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID1).isStopped());
375 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID1).containsPort(portno3));
376
377 // discovery on device is expected to be stopped for this device
378 LinkDiscovery linkDiscovery = provider.discoverers.get(DID2);
379 if (linkDiscovery != null) {
380 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
381 }
382 }
383
384 /**
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700385 * Checks that discovery on reconfigured port are properly restarted.
386 */
387 @Test
388 public void portSuppressedByPortConfig() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600389
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700390 // add device in stub DeviceService without suppression configured
391 deviceService.putDevice(device(DID3));
392 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
393
394 // suppressed port added to non-suppressed device
395 final long portno3 = 3L;
396 final Port port3 = port(DID3, portno3, true,
397 DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800398 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700399 .build());
400 deviceService.putPorts(DID3, port3);
401 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
402
403 // discovery helper should be there turned on
404 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
405 assertFalse("Discoverer should not contain the port there",
406 provider.discoverers.get(DID3).containsPort(portno3));
407 }
408
409 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800410 public void portSuppressedByPortBlacklist() {
411
412 // add device in stub DeviceService without suppression configured
413 deviceService.putDevice(device(DID3));
414 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
415
416 final long portno3 = 3L;
417 final Port port3 = port(DID3, portno3, true);
418
419 final ConnectPoint cpDid3no3 = new ConnectPoint(DID3, PortNumber.portNumber(portno3));
420 portBlacklist.add(cpDid3no3);
421
422 // suppressed port added to non-suppressed device
423 deviceService.putPorts(DID3, port3);
424 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
425
426 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
427 cpDid3no3,
428 LinkDiscoveryFromPort.class));
429
430 // discovery helper should be there turned on
431 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
432 // but port is not a discovery target
433 assertFalse("Discoverer should not contain the port there",
434 provider.discoverers.get(DID3).containsPort(portno3));
435 }
436
437 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700438 public void portUnknown() {
439 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700440 // Note: DID3 hasn't been added to TestDeviceService, but only port is added
441 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, 1, false)));
alshabib0ed6a202014-10-19 12:42:57 -0700442
443
alshabibdfc7afb2014-10-21 20:13:27 -0700444 assertNull("DeviceId exists",
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700445 provider.discoverers.get(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700446 }
447
448 @Test
449 public void unknownPktCtx() {
450
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700451 // Note: DID3 hasn't been added to TestDeviceService
452 PacketContext pktCtx = new TestPacketContext(device(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700453
454 testProcessor.process(pktCtx);
455 assertFalse("Context should still be free", pktCtx.isHandled());
456 }
457
458 @Test
459 public void knownPktCtx() {
460 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
461 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
462 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
463
464
465 testProcessor.process(pktCtx);
466
467 assertTrue("Link not detected", detectedLink(DID1, DID2));
468
469 }
470
471
472 @After
473 public void tearDown() {
474 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800475 provider.coreService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700476 provider.providerRegistry = null;
477 provider.deviceService = null;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800478 provider.packetService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700479 }
480
481 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
482 return new DeviceEvent(type, deviceService.getDevice(did));
483
484 }
485
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700486 private DefaultDevice device(DeviceId did) {
487 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
488 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
489 }
490
Naoki Shiota399a0b32015-11-15 20:36:13 -0600491 private DefaultDevice device(DeviceId did, Device.Type type) {
492 return new DefaultDevice(ProviderId.NONE, did, type,
493 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
494 }
495
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700496 private DefaultDevice device(DeviceId did, Annotations annotations) {
497 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
498 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId(), annotations);
499 }
500
Saurav Dasc313c402015-02-27 10:09:47 -0800501 @SuppressWarnings(value = { "unused" })
alshabib0ed6a202014-10-19 12:42:57 -0700502 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
503 return new DeviceEvent(type, deviceService.getDevice(did),
504 deviceService.getPort(did, port));
505 }
506
507 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
508 return new DeviceEvent(type, deviceService.getDevice(did), port);
509 }
510
511 private Port port(DeviceId did, long port, boolean enabled) {
512 return new DefaultPort(deviceService.getDevice(did),
513 PortNumber.portNumber(port), enabled);
514 }
515
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700516 private Port port(DeviceId did, long port, boolean enabled, Annotations annotations) {
517 return new DefaultPort(deviceService.getDevice(did),
518 PortNumber.portNumber(port), enabled, annotations);
519 }
alshabib0ed6a202014-10-19 12:42:57 -0700520
521 private boolean vanishedDpid(DeviceId... dids) {
522 for (int i = 0; i < dids.length; i++) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800523 if (!providerService.vanishedDpid().contains(dids[i])) {
alshabib0ed6a202014-10-19 12:42:57 -0700524 return false;
525 }
526 }
527 return true;
528 }
529
530 private boolean vanishedPort(Long... ports) {
531 for (int i = 0; i < ports.length; i++) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800532 if (!providerService.vanishedPort().contains(ports[i])) {
alshabib0ed6a202014-10-19 12:42:57 -0700533 return false;
534 }
535 }
536 return true;
537 }
538
539 private boolean detectedLink(DeviceId src, DeviceId dst) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800540 for (DeviceId key : providerService.discoveredLinks().keySet()) {
alshabib0ed6a202014-10-19 12:42:57 -0700541 if (key.equals(src)) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800542 return providerService.discoveredLinks().get(src).equals(dst);
alshabib0ed6a202014-10-19 12:42:57 -0700543 }
544 }
545 return false;
546 }
547
Naoki Shiota399a0b32015-11-15 20:36:13 -0600548 @Test
549 public void addDeviceTypeRule() {
550 Device.Type deviceType1 = Device.Type.ROADM;
551 Device.Type deviceType2 = Device.Type.SWITCH;
552
553 Set<Device.Type> deviceTypes = new HashSet<>();
554 deviceTypes.add(deviceType1);
555
556 cfg.deviceTypes(deviceTypes);
557
558 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
559
560 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
561 assertFalse(provider.rules().getSuppressedDeviceType().contains(deviceType2));
562 }
563
564 @Test
565 public void updateDeviceTypeRule() {
566 Device.Type deviceType1 = Device.Type.ROADM;
567 Device.Type deviceType2 = Device.Type.SWITCH;
568 Set<Device.Type> deviceTypes = new HashSet<>();
569
570 deviceTypes.add(deviceType1);
571 cfg.deviceTypes(deviceTypes);
572
573 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
574
575 deviceTypes.add(deviceType2);
576 cfg.deviceTypes(deviceTypes);
577
578 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
579
580 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
581 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType2));
582 }
583
584 @Test
585 public void addAnnotationRule() {
586 final String key1 = "key1", key2 = "key2";
587 final String value1 = "value1";
588
589 Map<String, String> annotation = new HashMap<>();
590 annotation.put(key1, value1);
591
592 cfg.annotation(annotation);
593
594 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
595
596 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
597 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
598 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
599 }
600
601 @Test
602 public void updateAnnotationRule() {
603 final String key1 = "key1", key2 = "key2";
604 final String value1 = "value1", value2 = "value2";
605 Map<String, String> annotation = new HashMap<>();
606
607 annotation.put(key1, value1);
608 cfg.annotation(annotation);
609
610 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
611
612 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
613 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
614 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
615
616 annotation.put(key2, value2);
617 cfg.annotation(annotation);
618
619 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
620
621 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
622 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
623 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key2));
624 assertEquals(value2, provider.rules().getSuppressedAnnotation().get(key2));
625 }
626
627 private void configEvent(NetworkConfigEvent.Type evType) {
628 configListener.event(new NetworkConfigEvent(evType,
629 appId,
630 SuppressionConfig.class));
631 }
632
alshabib0ed6a202014-10-19 12:42:57 -0700633 private class TestPacketContext implements PacketContext {
634
635 protected Device device;
636 protected boolean blocked = false;
637
638 public TestPacketContext(Device dev) {
639 device = dev;
640 }
641
642 @Override
643 public long time() {
644 return 0;
645 }
646
647 @Override
648 public InboundPacket inPacket() {
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800649 ONOSLLDP lldp = ONOSLLDP.onosLLDP(deviceService.getDevice(DID1).id().toString(),
650 device.chassisId(),
651 (int) pd1.number().toLong());
alshabib0ed6a202014-10-19 12:42:57 -0700652
653 Ethernet ethPacket = new Ethernet();
654 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
655 ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
656 ethPacket.setPayload(lldp);
657 ethPacket.setPad(true);
658
alshabib0ed6a202014-10-19 12:42:57 -0700659 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
660
661 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
662
663 return new DefaultInboundPacket(cp, ethPacket,
664 ByteBuffer.wrap(ethPacket.serialize()));
665
666 }
667
668 @Override
669 public OutboundPacket outPacket() {
670 return null;
671 }
672
673 @Override
674 public TrafficTreatment.Builder treatmentBuilder() {
675 return null;
676 }
677
678 @Override
679 public void send() {
680
681 }
682
683 @Override
684 public boolean block() {
685 blocked = true;
686 return blocked;
687 }
688
689 @Override
690 public boolean isHandled() {
691 return blocked;
692 }
693
694 }
695
Thomas Vachuska27bee092015-06-23 19:03:10 -0700696 private class TestPacketService extends PacketServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700697 @Override
698 public void addProcessor(PacketProcessor processor, int priority) {
699 testProcessor = processor;
700 }
alshabib0ed6a202014-10-19 12:42:57 -0700701 }
702
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800703 private class TestDeviceService extends DeviceServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700704
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700705 private final Map<DeviceId, Device> devices = new HashMap<>();
alshabib0ed6a202014-10-19 12:42:57 -0700706 private final ArrayListMultimap<DeviceId, Port> ports =
707 ArrayListMultimap.create();
alshabib0ed6a202014-10-19 12:42:57 -0700708 public TestDeviceService() {
709 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
710 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
711 Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH,
712 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
713 devices.put(DID1, d1);
714 devices.put(DID2, d2);
alshabib0ed6a202014-10-19 12:42:57 -0700715 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
716 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
717 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
718 pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true);
719
720 ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
721 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
alshabib0ed6a202014-10-19 12:42:57 -0700722 }
723
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700724 private void putDevice(Device device) {
725 DeviceId deviceId = device.id();
726 devices.put(deviceId, device);
727 }
728
729 private void putPorts(DeviceId did, Port...ports) {
730 this.ports.putAll(did, Lists.newArrayList(ports));
731 }
732
alshabib0ed6a202014-10-19 12:42:57 -0700733 @Override
734 public int getDeviceCount() {
735 return devices.values().size();
736 }
737
738 @Override
739 public Iterable<Device> getDevices() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700740 return ImmutableList.copyOf(devices.values());
alshabib0ed6a202014-10-19 12:42:57 -0700741 }
742
743 @Override
744 public Device getDevice(DeviceId deviceId) {
745 return devices.get(deviceId);
746 }
747
748 @Override
749 public MastershipRole getRole(DeviceId deviceId) {
750 return MastershipRole.MASTER;
751 }
752
753 @Override
754 public List<Port> getPorts(DeviceId deviceId) {
755 return ports.get(deviceId);
756 }
757
758 @Override
759 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
760 for (Port p : ports.get(deviceId)) {
761 if (p.number().equals(portNumber)) {
762 return p;
763 }
764 }
765 return null;
766 }
767
768 @Override
769 public boolean isAvailable(DeviceId deviceId) {
770 return true;
771 }
772
773 @Override
774 public void addListener(DeviceListener listener) {
775 deviceListener = listener;
776
777 }
778
779 @Override
780 public void removeListener(DeviceListener listener) {
781
782 }
783 }
784
785 private final class TestMasterShipService implements MastershipService {
786
787 @Override
788 public MastershipRole getLocalRole(DeviceId deviceId) {
789 return MastershipRole.MASTER;
790 }
791
792 @Override
Madan Jampanide003d92015-05-11 17:14:20 -0700793 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
794 return CompletableFuture.completedFuture(null);
alshabib0ed6a202014-10-19 12:42:57 -0700795 }
796
797 @Override
Madan Jampanic6e574f2015-05-29 13:41:52 -0700798 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
799 return null;
alshabib0ed6a202014-10-19 12:42:57 -0700800 }
801
802 @Override
803 public NodeId getMasterFor(DeviceId deviceId) {
804 return null;
805 }
806
807 @Override
808 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
809 return null;
810 }
811
812 @Override
alshabib0ed6a202014-10-19 12:42:57 -0700813 public void addListener(MastershipListener listener) {
814
815 }
816
817 @Override
818 public void removeListener(MastershipListener listener) {
819
820 }
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700821
822 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700823 public RoleInfo getNodesFor(DeviceId deviceId) {
824 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700825 }
alshabib0ed6a202014-10-19 12:42:57 -0700826 }
827
828
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700829 private class TestLinkService extends LinkServiceAdapter {
830 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600831
832 private final class TestNetworkConfigRegistry
833 extends NetworkConfigRegistryAdapter {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800834 @SuppressWarnings("unchecked")
Naoki Shiota399a0b32015-11-15 20:36:13 -0600835 @Override
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800836 public <S, C extends Config<S>> C getConfig(S subj, Class<C> configClass) {
837 if (configClass == SuppressionConfig.class) {
838 return (C) cfg;
839 } else if (configClass == LinkDiscoveryFromDevice.class) {
840 return (C) new LinkDiscoveryFromDevice() {
841 @Override
842 public boolean enabled() {
843 return !deviceBlacklist.contains(subj);
844 }
845 };
846 } else if (configClass == LinkDiscoveryFromPort.class) {
847 return (C) new LinkDiscoveryFromPort() {
848 @Override
849 public boolean enabled() {
850 return !portBlacklist.contains(subj);
851 }
852 };
853 } else {
854 return null;
855 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600856 }
857
858 @Override
859 public void addListener(NetworkConfigListener listener) {
860 configListener = listener;
861 }
862 }
863
864 private final class TestSuppressionConfig extends SuppressionConfig {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600865 private Set<Device.Type> deviceTypes = new HashSet<>(DEFAULT_RULES.getSuppressedDeviceType());
866 private Map<String, String> annotation = new HashMap<>(DEFAULT_RULES.getSuppressedAnnotation());
867
868 @Override
Naoki Shiota399a0b32015-11-15 20:36:13 -0600869 public Set<Device.Type> deviceTypes() {
870 return ImmutableSet.copyOf(deviceTypes);
871 }
872
873 @Override
874 public SuppressionConfig deviceTypes(Set<Device.Type> deviceTypes) {
875 this.deviceTypes = ImmutableSet.copyOf(deviceTypes);
876 return this;
877 }
878
879 @Override
880 public Map<String, String> annotation() {
881 return ImmutableMap.copyOf(annotation);
882 }
883
884 @Override
885 public SuppressionConfig annotation(Map<String, String> annotation) {
886 this.annotation = ImmutableMap.copyOf(annotation);
887 return this;
888 }
889 }
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800890
891 private final class TestMetadataService implements ClusterMetadataService {
892 @Override
893 public ClusterMetadata getClusterMetadata() {
894 final NodeId nid = new NodeId("test-node");
895 final IpAddress addr = IpAddress.valueOf(0);
Madan Jampani8474fdd2016-01-19 09:56:28 -0800896 final Partition p = new DefaultPartition(PartitionId.from(1), Sets.newHashSet(nid));
Madan Jampaniad3c5262016-01-20 00:50:17 -0800897 return new ClusterMetadata("test-cluster",
898 Sets.newHashSet(new DefaultControllerNode(nid, addr)),
899 Sets.newHashSet(p));
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800900 }
901
902 @Override
Madan Jampaniab7e7cd2016-01-14 14:02:32 -0800903 public ControllerNode getLocalNode() {
904 return null;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800905 }
906
907 @Override
Madan Jampaniab7e7cd2016-01-14 14:02:32 -0800908 public void addListener(ClusterMetadataEventListener listener) {
909 }
910
911 @Override
912 public void removeListener(ClusterMetadataEventListener listener) {
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800913 }
914 }
alshabib0ed6a202014-10-19 12:42:57 -0700915}